*: add qasm, revamp bsc wrap magic, use nix cc toolchain
parent
1c37f0c695
commit
cfa97935c0
3
.bazelrc
3
.bazelrc
|
@ -1,3 +1,6 @@
|
|||
build --host_platform=@io_tweag_rules_nixpkgs//nixpkgs/platforms:host
|
||||
build --incompatible_use_cc_configure_from_rules_cc
|
||||
build --host_crosstool_top=@local_config_cc//:toolchain
|
||||
build --platforms=//build/platforms:ulx3s_85f
|
||||
build --experimental_allow_unresolved_symlinks
|
||||
build --host_cxxopt='-std=c++17'
|
||||
|
|
49
WORKSPACE
49
WORKSPACE
|
@ -4,6 +4,12 @@ workspace(
|
|||
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_archive(
|
||||
name = "rules_cc",
|
||||
urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.0.1/rules_cc-0.0.1.tar.gz"],
|
||||
sha256 = "4dccbfd22c0def164c8f47458bd50e0c7148f3d92002cdb459c2a96a68498241",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "io_tweag_rules_nixpkgs",
|
||||
strip_prefix = "rules_nixpkgs-81f61c4b5afcf50665b7073f7fce4c1755b4b9a3",
|
||||
|
@ -14,30 +20,55 @@ http_archive(
|
|||
load("@io_tweag_rules_nixpkgs//nixpkgs:repositories.bzl", "rules_nixpkgs_dependencies")
|
||||
rules_nixpkgs_dependencies()
|
||||
|
||||
load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_git_repository", "nixpkgs_package")
|
||||
load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_git_repository", "nixpkgs_package", "nixpkgs_cc_configure")
|
||||
|
||||
nixpkgs_git_repository(
|
||||
name = "nixpkgs",
|
||||
revision = "ea25862403b62189b0e4256d1a17ed611f0d88bf",
|
||||
sha256 = "2a7a0e10461382470b1196f60d0ab173d090d0030526f517b1716e9cf318ef14",
|
||||
revision = "71ec7f4ad20b5c4c4a14d2a09f6040ade87c257d",
|
||||
sha256 = "f712f0586a3ffa693741ca1e62f26d366cc0f663041066a5b8f5606e930ff8b2",
|
||||
)
|
||||
|
||||
nixpkgs_cc_configure(
|
||||
name = "local_config_cc",
|
||||
repository = "@nixpkgs//:default.nix",
|
||||
)
|
||||
|
||||
nixpkgs_package(
|
||||
name = "bluespec",
|
||||
repositories = { "nixpkgs": "@nixpkgs//:default.nix" },
|
||||
build_file_content = """
|
||||
load("@qfc//build:utils.bzl", "external_binary_tool")
|
||||
load("@qfc//build/bluespec:rules.bzl", "bluespec_toolchain")
|
||||
|
||||
external_binary_tool(
|
||||
sh_binary(
|
||||
name = "bsc",
|
||||
bin = "bin/bsc",
|
||||
deps = glob(["lib/**", "bin/core/**"]),
|
||||
data = [
|
||||
"bin/bsc"
|
||||
] + glob(["lib/**", "bin/core/**"]),
|
||||
srcs = [
|
||||
"@qfc//build/bluespec:bsc.sh",
|
||||
],
|
||||
deps = [
|
||||
"@bazel_tools//tools/bash/runfiles",
|
||||
],
|
||||
)
|
||||
|
||||
sh_binary(
|
||||
name = "bluetcl",
|
||||
data = [
|
||||
"bin/bluetcl"
|
||||
] + glob(["lib/**", "bin/core/**"]),
|
||||
srcs = [
|
||||
"@qfc//build/bluespec:bluetcl.sh",
|
||||
],
|
||||
deps = [
|
||||
"@bazel_tools//tools/bash/runfiles",
|
||||
],
|
||||
)
|
||||
|
||||
bluespec_toolchain(
|
||||
name = "bsc_nixpkgs",
|
||||
bsc = ":bsc",
|
||||
bluetcl = ":bluetcl",
|
||||
verilog_lib = glob(["lib/Verilog/*.v"], [
|
||||
"lib/Verilog/BRAM2.v",
|
||||
"lib/Verilog/BRAM2Load.v",
|
||||
|
@ -64,9 +95,9 @@ toolchain(
|
|||
|
||||
nixpkgs_package(
|
||||
name = "yosysflow",
|
||||
repositories = { "nixpkgs1": "@nixpkgs//:default.nix" },
|
||||
repositories = { "nixpkgs2": "@nixpkgs//:default.nix" },
|
||||
nix_file_content = """
|
||||
with import <nixpkgs1> {}; symlinkJoin {
|
||||
with import <nixpkgs2> {}; symlinkJoin {
|
||||
name = "yosysflow";
|
||||
paths = with pkgs; [ yosys nextpnr trellis ];
|
||||
}
|
||||
|
|
|
@ -14,7 +14,18 @@ bluespec_library(
|
|||
"Board": ["mkTop", "mkMemory"],
|
||||
},
|
||||
data = [
|
||||
"bram.bin",
|
||||
":bram",
|
||||
],
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "bram",
|
||||
tools = [
|
||||
"//lanai/qasm",
|
||||
],
|
||||
cmd = "$(location //lanai/qasm) $@",
|
||||
outs = [
|
||||
"bram.bin"
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -21,7 +21,8 @@ endinterface
|
|||
|
||||
(* synthesize *)
|
||||
module mkMemory(Lanai_Memory#(1024));
|
||||
Lanai_Memory#(1024) inner <- mkBlockMemory("boards/ulx3s/bram.bin");
|
||||
// TODO(q3k): ... figure out how the fuck to unhardcode this.
|
||||
Lanai_Memory#(1024) inner <- mkBlockMemory("bazel-out/k8-fastbuild/bin/boards/ulx3s/bram.bin");
|
||||
interface dmem = inner.dmem;
|
||||
interface imem = inner.imem;
|
||||
endmodule
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,3 +11,5 @@ cc_binary(
|
|||
],
|
||||
visibility = [ "//visibility:public" ],
|
||||
)
|
||||
|
||||
exports_files(["bluetcl.sh", "bsc.sh"])
|
||||
|
|
|
@ -10,11 +10,40 @@
|
|||
#include <string>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
auto bsc = std::getenv("BSC");
|
||||
if (bsc == nullptr) {
|
||||
std::cerr << "BSC must be set\n";
|
||||
char **new_argv = new char*[argc];
|
||||
int new_argv_ix = 0;
|
||||
|
||||
char *bsc = nullptr;
|
||||
char *cxx = nullptr;
|
||||
char *strip = nullptr;
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (new_argv_ix > 0) {
|
||||
new_argv[new_argv_ix++] = argv[i];
|
||||
} else {
|
||||
if (std::string(argv[i]) == "--") {
|
||||
new_argv_ix = 1;
|
||||
} else {
|
||||
switch (i) {
|
||||
case 1:
|
||||
bsc = argv[1];
|
||||
break;
|
||||
case 2:
|
||||
cxx = argv[i];
|
||||
break;
|
||||
case 3:
|
||||
strip = argv[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bsc == nullptr || cxx == nullptr || strip == nullptr) {
|
||||
std::cerr << "Usage: " << argv[0] << " bsc cxx strip -- bsc args\n";
|
||||
return 1;
|
||||
}
|
||||
new_argv[0] = bsc;
|
||||
new_argv[new_argv_ix] = nullptr;
|
||||
|
||||
auto tmp = std::getenv("TMPDIR");
|
||||
if (tmp == nullptr) {
|
||||
|
@ -27,18 +56,8 @@ int main(int argc, char **argv) {
|
|||
std::filesystem::remove_all(forest);
|
||||
std::filesystem::create_directory(forest);
|
||||
|
||||
std::map<std::string, std::string> links = {
|
||||
{"c++", "CXX"},
|
||||
{"strip", "STRIP"},
|
||||
};
|
||||
for (auto const& [k, v] : links) {
|
||||
auto target = std::getenv(v.c_str());
|
||||
if (target == nullptr) {
|
||||
std::cerr << v << " must be set\n";
|
||||
return 1;
|
||||
}
|
||||
std::filesystem::create_symlink(target, forest + "/" + k);
|
||||
}
|
||||
std::filesystem::create_symlink(cxx, forest + "/c++");
|
||||
std::filesystem::create_symlink(strip, forest + "/strip");
|
||||
|
||||
auto path = forest + ":" + (std::getenv("PATH") ? std::getenv("PATH") : "");
|
||||
|
||||
|
@ -47,7 +66,7 @@ int main(int argc, char **argv) {
|
|||
nullptr,
|
||||
};
|
||||
|
||||
if (execvpe(bsc, argv, envp) == -1) {
|
||||
if (execvpe(bsc, new_argv, envp) == -1) {
|
||||
std::cerr << "execvpe failed\n";
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ def _bluespec_toolchain_impl(ctx):
|
|||
toolchain_info = platform_common.ToolchainInfo(
|
||||
bscinfo = BscInfo(
|
||||
bsc = ctx.attr.bsc,
|
||||
bluetcl = ctx.attr.bluetcl,
|
||||
verilog_lib = VerilogInfo(
|
||||
sources = depset(ctx.files.verilog_lib),
|
||||
),
|
||||
|
@ -19,6 +20,10 @@ bluespec_toolchain = rule(
|
|||
executable = True,
|
||||
cfg = "exec",
|
||||
),
|
||||
"bluetcl": attr.label(
|
||||
executable = True,
|
||||
cfg = "exec",
|
||||
),
|
||||
"verilog_lib": attr.label_list(
|
||||
allow_files = True,
|
||||
),
|
||||
|
@ -27,7 +32,6 @@ bluespec_toolchain = rule(
|
|||
|
||||
def _compile(ctx, src, dep_objs, output, mode, verilog_outputs=[], sim_outputs=[]):
|
||||
info = ctx.toolchains["@qfc//build/bluespec:toolchain_type"].bscinfo
|
||||
bsc = info.bsc[DefaultInfo].files_to_run
|
||||
|
||||
bdir = output.dirname
|
||||
pkg_path_set = {}
|
||||
|
@ -67,18 +71,23 @@ def _compile(ctx, src, dep_objs, output, mode, verilog_outputs=[], sim_outputs=[
|
|||
src.path,
|
||||
]
|
||||
|
||||
_, _, input_manifests = ctx.resolve_command(tools = [info.bsc])
|
||||
ctx.actions.run(
|
||||
mnemonic = mnemonic,
|
||||
executable = bsc,
|
||||
executable = info.bsc.files_to_run,
|
||||
arguments = arguments,
|
||||
inputs = depset([ src ], transitive=[dep_objs]),
|
||||
outputs = sim_outputs + verilog_outputs + [ output ],
|
||||
input_manifests = input_manifests,
|
||||
use_default_shell_env = True,
|
||||
env = {
|
||||
"PATH": ctx.configuration.default_shell_env.get('PATH', ""),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def _library_inner(ctx):
|
||||
info = ctx.toolchains["@qfc//build/bluespec:toolchain_type"].bscinfo
|
||||
bsc = info.bsc[DefaultInfo].files_to_run
|
||||
|
||||
package_order = []
|
||||
package_to_src = {}
|
||||
|
@ -247,6 +256,7 @@ def _bluesim_test_impl(ctx):
|
|||
info = ctx.toolchains["@qfc//build/bluespec:toolchain_type"].bscinfo
|
||||
cc_toolchain = find_cpp_toolchain(ctx)
|
||||
bsc = info.bsc
|
||||
bluetcl = info.bluetcl
|
||||
|
||||
sim_objs = depset(
|
||||
[],
|
||||
|
@ -264,7 +274,7 @@ def _bluesim_test_impl(ctx):
|
|||
] + [
|
||||
dep[BluespecInfo].data_files
|
||||
for dep in ctx.attr.deps
|
||||
],
|
||||
] + [ bluetcl.default_runfiles.files ],
|
||||
)
|
||||
|
||||
pkg_path_set = {}
|
||||
|
@ -283,18 +293,22 @@ def _bluesim_test_impl(ctx):
|
|||
# information into bsc somehow. Maybe using a real linker?
|
||||
if cxx.endswith('/gcc'):
|
||||
cxx = cxx[:-2] + "++"
|
||||
elif cxx.endswith('/cc'):
|
||||
cxx = cxx[:-2] + "g++"
|
||||
|
||||
ctx.actions.run(
|
||||
mnemonic = "BluespecSimLink",
|
||||
executable = ctx.executable._bscwrap,
|
||||
tools = [
|
||||
bsc[DefaultInfo].files_to_run,
|
||||
bsc.files_to_run
|
||||
],
|
||||
inputs = depset(
|
||||
[],
|
||||
transitive = [ bsc.files, sim_objs, sim_outputs ],
|
||||
transitive = [ sim_objs, sim_outputs ],
|
||||
),
|
||||
arguments = [
|
||||
bsc.files_to_run.executable.path, cxx, cc_toolchain.strip_executable,
|
||||
"--",
|
||||
"-p", ":".join(pkg_path),
|
||||
"-sim",
|
||||
"-simdir", test.dirname,
|
||||
|
@ -302,29 +316,36 @@ def _bluesim_test_impl(ctx):
|
|||
"-e",
|
||||
ctx.attr.top,
|
||||
],
|
||||
env = {
|
||||
"CXX": cxx,
|
||||
"STRIP": cc_toolchain.strip_executable,
|
||||
"BSC": bsc[DefaultInfo].files_to_run.executable.path,
|
||||
"PATH": ctx.configuration.default_shell_env.get('PATH', ""),
|
||||
},
|
||||
use_default_shell_env = True,
|
||||
outputs = [test, testSo]
|
||||
)
|
||||
|
||||
wrapper = ctx.actions.declare_file(ctx.attr.name + ".wrap")
|
||||
test_path = ctx.workspace_name + "/" + test.short_path
|
||||
ctx.actions.write(
|
||||
output = wrapper,
|
||||
content = """#!/bin/sh
|
||||
t="{}"
|
||||
$t $@ >res 2>&1
|
||||
cat res
|
||||
if grep -q "Error:" res ; then
|
||||
exit 1
|
||||
fi
|
||||
if grep -q "Dynamic assertion failed:" res ; then
|
||||
exit 1
|
||||
fi
|
||||
""".format(test.short_path),
|
||||
content = """#!/usr/bin/env bash
|
||||
# --- begin runfiles.bash initialization v2 ---
|
||||
# Copy-pasted from the Bazel Bash runfiles library v2.
|
||||
set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash
|
||||
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \\
|
||||
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \\
|
||||
source "$0.runfiles/$f" 2>/dev/null || \\
|
||||
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \\
|
||||
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \\
|
||||
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
|
||||
# --- end runfiles.bash initialization v2 --- """ + ("""
|
||||
export PATH="$(dirname $(rlocation bluespec/bluetcl)):$PATH"
|
||||
t="$(rlocation {})"
|
||||
$t $@ >res 2>&1
|
||||
cat res
|
||||
if grep -q "Error:" res ; then
|
||||
exit 1
|
||||
fi
|
||||
if grep -q "Dynamic assertion failed:" res ; then
|
||||
exit 1
|
||||
fi
|
||||
""".format(test_path)),
|
||||
is_executable = True,
|
||||
)
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
BscInfo = provider(
|
||||
fields = [
|
||||
"bsc",
|
||||
"bluetcl",
|
||||
"verilog_lib",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
def _external_binary_tool_impl(ctx):
|
||||
bin_ = ctx.file.bin
|
||||
|
||||
executable = ctx.actions.declare_file(ctx.attr.name + ".bin")
|
||||
path = ctx.file.bin.path
|
||||
strip = "external/"
|
||||
if not path.startswith(strip):
|
||||
fail("Unexpected path {}".format(path))
|
||||
path = path[len(strip):]
|
||||
path = executable.path + ".runfiles/" + ctx.workspace_name + "/" + ctx.file.bin.short_path
|
||||
ctx.actions.write(
|
||||
output = executable,
|
||||
content = """#!/bin/sh
|
||||
sp="{}"
|
||||
bin=$0.runfiles/$sp
|
||||
exec $bin $@
|
||||
exec "{}" $@
|
||||
""".format(path),
|
||||
is_executable = True,
|
||||
)
|
||||
|
|
|
@ -35,7 +35,18 @@ bluespec_library(
|
|||
":Lanai",
|
||||
],
|
||||
data = [
|
||||
"bram.bin",
|
||||
":bram",
|
||||
],
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "bram",
|
||||
tools = [
|
||||
"//lanai/qasm",
|
||||
],
|
||||
cmd = "$(location //lanai/qasm) $@",
|
||||
outs = [
|
||||
"bram.bin"
|
||||
],
|
||||
)
|
||||
|
||||
|
|
8192
lanai/bram.bin
8192
lanai/bram.bin
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,9 @@
|
|||
py_binary(
|
||||
name = "qasm",
|
||||
srcs = [
|
||||
"qasm.py",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,274 @@
|
|||
# qasm - the quaint lanai assembler.
|
||||
#
|
||||
# This is meant to be used for testing only.
|
||||
|
||||
import math
|
||||
import struct
|
||||
|
||||
def serialize(l):
|
||||
bs = []
|
||||
for (nbits, val) in l:
|
||||
val = int(val)
|
||||
if val > 0 and math.log(val, 2) > nbits:
|
||||
raise Exception('too wide, {} bits, {}', nbits, val)
|
||||
bs.append(('{:0'+str(nbits)+'b}').format(val))
|
||||
return '_'.join(bs)
|
||||
|
||||
def op3bit(opcode):
|
||||
return {
|
||||
'add': 0, 'addc': 1, 'sub': 2, 'subb': 3, 'and': 4, 'or': 5, 'xor': 6,
|
||||
'sh': 7, 'sha': 7,
|
||||
}[opcode]
|
||||
|
||||
def op7bit(opcode):
|
||||
if opcode == 'sh':
|
||||
return 0b11110000
|
||||
if opcode == 'sha':
|
||||
return 0b11111000
|
||||
if opcode == 'sel':
|
||||
return 0b11100000
|
||||
return op3bit(opcode) << 5
|
||||
|
||||
def ri(opcode, rd, rs, flags, const):
|
||||
high = False
|
||||
if opcode in ['sh', 'sha']:
|
||||
if const > 31 or const < -31:
|
||||
raise Exception('invalid shift amount')
|
||||
const, = struct.unpack('>H', struct.pack('>h', const))
|
||||
high = opcode == 'sha'
|
||||
|
||||
else:
|
||||
if (const & 0xffff) == 0:
|
||||
high = True
|
||||
const = const >> 16
|
||||
else:
|
||||
if (const >> 16) != 0:
|
||||
raise Exception("invalid constant {:032x}".format(const))
|
||||
return serialize([
|
||||
(1, 0),
|
||||
(3, op3bit(opcode)),
|
||||
(5, rd),
|
||||
(5, rs),
|
||||
(1, flags),
|
||||
(1, high),
|
||||
(16, const),
|
||||
])
|
||||
|
||||
def rr(opcode, rd, rs1, flags, rs2, condition):
|
||||
return serialize([
|
||||
(4, 0b1100),
|
||||
(5, rd),
|
||||
(5, rs1),
|
||||
(1, flags),
|
||||
(1, condition & 1),
|
||||
(5, rs2),
|
||||
(8, op7bit(opcode)),
|
||||
(3, condition >> 1),
|
||||
])
|
||||
|
||||
def rm(store, rd, rs1, p, q, constant):
|
||||
return serialize([
|
||||
(3, 0b100),
|
||||
(1, store),
|
||||
(5, rd),
|
||||
(5, rs1),
|
||||
(1, p),
|
||||
(1, q),
|
||||
(16, constant),
|
||||
])
|
||||
|
||||
def regno(name):
|
||||
val = {
|
||||
'pc': 2, 'sw': 3, 'rv': 8, 'rr1': 10, 'rr2': 11,
|
||||
}.get(name)
|
||||
if val is not None:
|
||||
return val
|
||||
return int(name[1:])
|
||||
|
||||
def condno(name):
|
||||
return {
|
||||
't': 0, 'f': 1, 'hi': 2, 'ls': 3, 'cc': 4, 'cs': 5, 'ne': 6, 'eq': 7,
|
||||
'vc': 8, 'vs': 9, 'pl': 10, 'mi': 11, 'ge': 12, 'lt': 13, 'gt': 14,
|
||||
'le': 15
|
||||
}[name]
|
||||
|
||||
def asm(text):
|
||||
parts = text.split()
|
||||
opcode = parts[0]
|
||||
flags = opcode.endswith('.f')
|
||||
if flags:
|
||||
opcode = opcode[:-2]
|
||||
operands = [p.strip(',') for p in parts[1:]]
|
||||
registers = [regno(el[1:]) if el.startswith('%') else None for el in operands]
|
||||
imms = []
|
||||
for el in operands:
|
||||
try:
|
||||
val = int(el)
|
||||
except ValueError:
|
||||
try:
|
||||
val = int(el, 16)
|
||||
except ValueError:
|
||||
val = None
|
||||
imms.append(val)
|
||||
|
||||
if opcode in ['add', 'addc', 'sub', 'subb', 'and', 'or', 'xor', 'sh', 'sha']:
|
||||
if len(operands) != 3:
|
||||
raise Exception('invalid operand count {}'.format(text))
|
||||
[src1, src2, dest] = registers
|
||||
if dest is None:
|
||||
raise Exception('destination must be register')
|
||||
if src1 is None:
|
||||
raise Exception('source must be register')
|
||||
if src2 is None:
|
||||
return ri(opcode, dest, src1, flags, imms[1])
|
||||
else:
|
||||
return rr(opcode, dest, src1, flags, src2, 0)
|
||||
|
||||
if opcode.startswith('sel.'):
|
||||
cond = opcode.split('.')[1]
|
||||
[src1, src2, dest] = registers
|
||||
if dest is None:
|
||||
raise Exception('destination must be register')
|
||||
if src1 is None:
|
||||
raise Exception('source1 must be register')
|
||||
if src2 is None:
|
||||
raise Exception('source2 must be register')
|
||||
return rr('sel', dest, src1, flags, src2, condno(cond))
|
||||
|
||||
if opcode in ['ld', 'st']:
|
||||
if len(operands) != 2:
|
||||
raise Exception('invalid operand count {}'.format(text))
|
||||
mo = 0
|
||||
ro = 1
|
||||
if opcode == 'st':
|
||||
mo = 1
|
||||
ro = 0
|
||||
|
||||
parts = operands[mo].split('[')
|
||||
|
||||
offs = None
|
||||
if len(parts) == 1:
|
||||
offs = 0
|
||||
else:
|
||||
offs = parts[0]
|
||||
parts = parts[1:]
|
||||
|
||||
src = parts[0].split(']')[0]
|
||||
preincr = False
|
||||
postincr = False
|
||||
if src.endswith('++'):
|
||||
postincr = True
|
||||
offs = 4
|
||||
src = src[:-2]
|
||||
if src.endswith('*'):
|
||||
postincr = True
|
||||
src = src[:-1]
|
||||
if src.startswith('++'):
|
||||
preincr = True
|
||||
offs = 4
|
||||
src = src[2:]
|
||||
if src.startswith('*'):
|
||||
preincr = True
|
||||
src = src[1:]
|
||||
|
||||
dest = registers[ro]
|
||||
offs = int(offs)
|
||||
src = regno(src[1:])
|
||||
|
||||
p = False
|
||||
q = False
|
||||
if offs != 0:
|
||||
if preincr:
|
||||
p = True
|
||||
q = True
|
||||
elif postincr:
|
||||
q = True
|
||||
else:
|
||||
p = True
|
||||
|
||||
return rm(opcode == 'st', dest, src, p, q, offs)
|
||||
|
||||
|
||||
max_counter = int(25e6/7)
|
||||
#max_counter = 5
|
||||
|
||||
insns = {
|
||||
#0: 'add %r0, {}, %r16'.format(max_counter & 0xffff),
|
||||
#4: 'or %r16, {}, %r16'.format(max_counter & 0xffff0000),
|
||||
#8: 'add %r0, 0, %r7',
|
||||
#12: 'add %r0, 0, %r4',
|
||||
##16: 'add %r0, 0xf000, %r9',
|
||||
|
||||
##32: 'ld 0[%r9], %r14',
|
||||
##36: 'ld [%r9++], %r14',
|
||||
##40: 'ld 4[%r9], %r14',
|
||||
##44: 'ld [++%r9], %r14',
|
||||
|
||||
##64: 'st %r14, 0[%r9]',
|
||||
##68: 'st %r14, [%r9++]',
|
||||
##72: 'st %r14, 4[%r9]',
|
||||
##76: 'st %r14, [++%r9]',
|
||||
|
||||
#16: 'add %r4, 1, %r4',
|
||||
#20: 'add %r7, 1, %r17',
|
||||
#24: 'sub.f %r4, %r16, %r10',
|
||||
|
||||
#28: 'sel.pl %r17, %r7, %r7',
|
||||
#32: 'sel.pl %r0, %r4, %r4',
|
||||
#36: 'add %r0, 0x10, %pc',
|
||||
|
||||
#0: 'add %r0, {}, %r16'.format(max_counter & 0xffff),
|
||||
#4: 'or %r16, {}, %r16'.format(max_counter & 0xffff0000),
|
||||
#8: 'add %r0, 0, %r7',
|
||||
#12: 'add %r0, 0, %r4',
|
||||
|
||||
#16: 'add %r4, 1, %r4',
|
||||
#20: 'add %r7, 1, %r17',
|
||||
#24: 'sub.f %r4, %r16, %r0',
|
||||
|
||||
#28: 'sel.eq %r17, %r7, %r7',
|
||||
#32: 'sel.eq %r0, %r4, %r4',
|
||||
#36: 'add %r0, 0x10, %pc',
|
||||
|
||||
0: 'add %r0, 0xbee0, %r10',
|
||||
4: 'add %r0, 256, %r9',
|
||||
8: 'st %r10, 0[%r9]',
|
||||
12: 'ld 0[%r9++], %r11',
|
||||
16: 'add %r11, 1, %r7',
|
||||
20: 'add %r11, 2, %r7',
|
||||
24: 'add %r11, 3, %r7',
|
||||
28: 'add %r11, 4, %r7',
|
||||
|
||||
60: 'add %r0, 0, %r11',
|
||||
64: 'add %r0, 512, %r9',
|
||||
68: 'st %r10, 0[%r9]',
|
||||
72: 'ld 0[%r9++], %r11',
|
||||
76: 'add %r11, 1, %r7',
|
||||
80: 'add %r11, 2, %r7',
|
||||
84: 'add %r11, 3, %r7',
|
||||
88: 'add %r11, 4, %r7',
|
||||
|
||||
256: 'add %r0, 128, %pc',
|
||||
}
|
||||
|
||||
ram = [0 for i in range(2**15)]
|
||||
|
||||
for addr, ins in insns.items():
|
||||
ins = int(asm(ins).replace('_', ''), 2)
|
||||
ram[addr+0] = (ins >> 24 ) & 0xff
|
||||
ram[addr+1] = (ins >> 16 ) & 0xff
|
||||
ram[addr+2] = (ins >> 8 ) & 0xff
|
||||
ram[addr+3] = (ins >> 0 ) & 0xff
|
||||
|
||||
import sys
|
||||
with open(sys.argv[1], 'w') as f:
|
||||
for i in range(0, len(ram), 4):
|
||||
el = ram[i+0] << 24
|
||||
el |= ram[i+1] << 16
|
||||
el |= ram[i+2] << 8
|
||||
el |= ram[i+3]
|
||||
f.write('{:08x}\n'.format(el))
|
||||
|
||||
#with open('bram.bin', 'wb') as f:
|
||||
# for i in range(0, len(ram)):
|
||||
# f.write(bytes([ram[i]]))
|
Loading…
Reference in New Issue