Last active
April 7, 2021 10:09
-
-
Save kbeckmann/2980e9f7371e3ce8cc79a415e0a4248b to your computer and use it in GitHub Desktop.
Trying to run cxxrtl with a complex design
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from nmigen import * | |
from nmigen._toolchain.yosys import * | |
from nmigen.back.cxxrtl import rtlil | |
import os, subprocess | |
def _convert_rtlil_text(rtlil_text, black_boxes, verilog_boxes, *, src_loc_at=0): | |
if black_boxes is not None: | |
if not isinstance(black_boxes, dict): | |
raise TypeError("CXXRTL black boxes must be a dictionary, not {!r}" | |
.format(black_boxes)) | |
for box_name, box_source in black_boxes.items(): | |
if not isinstance(box_name, str): | |
raise TypeError("CXXRTL black box name must be a string, not {!r}" | |
.format(box_name)) | |
if not isinstance(box_source, str): | |
raise TypeError("CXXRTL black box source code must be a string, not {!r}" | |
.format(box_source)) | |
yosys = find_yosys(lambda ver: ver >= (0, 9, 3468)) | |
script = [] | |
if black_boxes is not None: | |
for box_name, box_source in black_boxes.items(): | |
script.append("read_ilang <<rtlil\n{}\nrtlil".format(box_source)) | |
# ------- Patch that adds verilog_boxes | |
if verilog_boxes is not None: | |
for box_name, box_source in verilog_boxes.items(): | |
script.append(f"read_verilog <<verilog_{box_name}\n{box_source}\nverilog_{box_name}") | |
# ------- | |
script.append("read_ilang <<rtlil\n{}\nrtlil".format(rtlil_text)) | |
script.append("delete w:$verilog_initial_trigger") | |
script.append("write_cxxrtl") | |
return yosys.run(["-q", "-"], "\n".join(script), src_loc_at=1 + src_loc_at, ignore_warnings=True) | |
def convert(*args, black_boxes=None, verilog_boxes=None, **kwargs): | |
rtlil_text = rtlil.convert(*args, **kwargs) | |
return _convert_rtlil_text(rtlil_text, black_boxes, verilog_boxes, src_loc_at=1) | |
def build_blinky(): | |
m = Module() | |
foo = Signal(32) | |
bar = Signal(32) | |
m.submodules.example = example = Instance("example", | |
i_clk=ClockSignal(), | |
i_foo=foo, | |
o_bar=bar, | |
) | |
example_v = """ | |
module example( | |
input wire clk, | |
input wire [31:0] foo, | |
output wire [31:0] bar | |
); | |
always @ (posedge clk) | |
begin | |
bar <= foo + bar + 42; | |
end | |
endmodule | |
""" | |
output = convert(m, ports=(foo, bar), verilog_boxes={"example": example_v}) | |
root = os.path.join("build") | |
if not os.path.exists(root): | |
os.mkdir("build") | |
filename = os.path.join(root, "top.cpp") | |
elfname = os.path.join(root, "top.elf") | |
with open(filename, "w") as f: | |
f.write(output) | |
f.write(''' | |
#include <iostream> | |
#include <fstream> | |
#include <backends/cxxrtl/cxxrtl_vcd.h> | |
int main(int argc, char *argv[]) | |
{ | |
cxxrtl_design::p_top top; | |
vcd_writer w; | |
if (argc != 2) { | |
std::cout << "Usage: " << argv[0] << " out.vcd" << std::endl; | |
return 1; | |
} | |
debug_items items; | |
top.debug_info(items); | |
w.add(items); | |
std::cout << "foo" << " " << "bar" << std::endl; | |
for (int i=0; i < 16; i++) { | |
if (i >= 8) { | |
top.p_foo = value<32>{100u}; | |
} | |
top.step(); | |
top.p_clk = value<1>{0u}; | |
top.step(); | |
top.p_clk = value<1>{1u}; | |
std::cout << top.p_foo << " " << top.p_bar << std::endl; | |
w.sample(i); | |
} | |
std::cout << "Writing " << argv[1] << std::endl; | |
std::ofstream outfile (argv[1]); | |
outfile << w.buffer; | |
outfile.close(); | |
return 0; | |
}''') | |
f.close() | |
print(subprocess.check_call([ | |
"clang++", "-I", "/usr/share/yosys/include", | |
"-O3", "-std=c++11", "-o", elfname, filename])) | |
print(subprocess.check_call([elfname, "build/top.vcd"])) | |
def build_chacha(): | |
import os | |
import subprocess | |
cs = Signal() | |
we = Signal() | |
addr = Signal(8) | |
write_data = Signal(32) | |
read_data = Signal(32) | |
m = Module() | |
m.submodules.chacha_top = chacha_top = Instance("chacha", | |
i_clk=ClockSignal(), | |
# i_reset_n=ResetSignal(), | |
i_reset_n=Const(1), | |
i_cs=cs, | |
i_we=we, | |
i_addr=addr, | |
i_write_data=write_data, | |
o_read_data=read_data, | |
) | |
# https://github.com/secworks/chacha | |
output = convert(m, ports=( | |
cs, | |
we, | |
addr, | |
write_data, | |
read_data), | |
verilog_boxes={ | |
"chacha.v": open("chacha.v").read(), | |
"chacha_core.v": open("chacha_core.v").read(), | |
"chacha_qr.v": open("chacha_qr.v").read(), | |
}) | |
root = os.path.join("build") | |
if not os.path.exists(root): | |
os.mkdir("build") | |
print("output -----------") | |
print(output) | |
print("------------------") | |
filename = os.path.join(root, "top.cpp") | |
elfname = os.path.join(root, "top.elf") | |
with open(filename, "w") as f: | |
f.write(output) | |
f.write(''' | |
#include <iostream> | |
#include <fstream> | |
#include <backends/cxxrtl/cxxrtl_vcd.h> | |
int main(int argc, char *argv[]) | |
{ | |
cxxrtl_design::p_top top; | |
vcd_writer w; | |
if (argc != 2) { | |
std::cout << "Usage: " << argv[0] << " out.vcd" << std::endl; | |
return 1; | |
} | |
debug_items items; | |
top.debug_info(items); | |
w.add(items); | |
top.step(); | |
top.p_clk = value<1>{0u}; | |
top.step(); | |
top.p_clk = value<1>{1u}; | |
top.p_cs = value<1>{1u}; | |
top.p_we = value<1>{1u}; | |
top.p_addr = value<8>{8u}; | |
top.p_data_write = value<32>{1u}; | |
for (int i=0; i < 64; i++) { | |
top.step(); | |
top.p_clk = value<1>{0u}; | |
top.step(); | |
top.p_clk = value<1>{1u}; | |
w.sample(i); | |
} | |
std::cout << "Writing " << argv[1] << std::endl; | |
std::ofstream outfile (argv[1]); | |
outfile << w.buffer; | |
outfile.close(); | |
return 0; | |
}''') | |
f.close() | |
print(subprocess.check_call([ | |
"clang++", "-I", "/usr/share/yosys/include", | |
"-O3", "-std=c++11", "-o", elfname, filename])) | |
print(subprocess.check_call([elfname, "build/top.vcd"])) | |
if __name__ == "__main__": | |
# Uncoment blinky to try it, it works fine | |
# build_blinky() | |
print("""Please download these files before running, then uncomment the last line | |
wget https://raw.githubusercontent.com/secworks/chacha/master/src/rtl/chacha.v | |
wget https://raw.githubusercontent.com/secworks/chacha/master/src/rtl/chacha_core.v | |
wget https://raw.githubusercontent.com/secworks/chacha/master/src/rtl/chacha_qr.v | |
""") | |
# build_chacha() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment