diff --git a/default.nix b/default.nix index 72034e0..08da0cb 100644 --- a/default.nix +++ b/default.nix @@ -19,7 +19,7 @@ rec { binutils-riscv = pkgs.callPackage ./compilers/binutils.nix { platform = "riscv32"; }; rust-riscv32imc-crates = pkgs.callPackage ./compilers/rust-riscv32imc-crates.nix { }; - helloworld = pkgs.callPackage ./firmware { inherit rust-riscv32imc-crates binutils-riscv; }; + fw-helloworld = pkgs.callPackage ./firmware { inherit rust-riscv32imc-crates binutils-riscv; }; }; lib = { symbiflow = import ./eda/symbiflow.nix { inherit pkgs; inherit (drvs) yosys; }; diff --git a/examples/simplesoc_ecp5.nix b/examples/simplesoc_ecp5.nix index 3ec7526..97b7379 100644 --- a/examples/simplesoc_ecp5.nix +++ b/examples/simplesoc_ecp5.nix @@ -7,7 +7,7 @@ let '' mkdir $out - python ${./simplesoc_ecp5.py} > $out/top.il + python ${./simplesoc_ecp5.py} ${hx.drvs.fw-helloworld}/helloworld.bin $out/top.il cat > $out/top.lpf << EOF LOCATE COMP "clk100" SITE "P3"; diff --git a/examples/simplesoc_ecp5.py b/examples/simplesoc_ecp5.py index 218e349..57d3962 100644 --- a/examples/simplesoc_ecp5.py +++ b/examples/simplesoc_ecp5.py @@ -1,3 +1,6 @@ +import argparse +import struct + from nmigen import * from nmigen.back import rtlil @@ -24,9 +27,10 @@ class SimpleWishboneSerial(Elaboratable): class Top(Elaboratable): - def __init__(self): + def __init__(self, firmware): self.clk100 = Signal() self.serial_tx = Signal() + self.firmware = firmware def elaborate(self, platform): m = Module() @@ -36,7 +40,7 @@ class Top(Elaboratable): m.d.comb += cd_sync.clk.eq(self.clk100) m.submodules.cpu = cpu = Minerva(with_icache=False, with_dcache=False, with_muldiv=False) - m.submodules.ram = ram = wishbone.SRAM(Memory(32, 1024)) + m.submodules.ram = ram = wishbone.SRAM(Memory(32, 1024, init=self.firmware)) m.submodules.uart = uart = SimpleWishboneSerial(self.serial_tx, 100e6) m.submodules.con = con = wishbone.InterconnectShared( [cpu.ibus, cpu.dbus], @@ -48,11 +52,30 @@ class Top(Elaboratable): return m +def read_firmware(file): + firmware = [] + with open(file, "rb") as f: + while True: + word = f.read(4) + if len(word) < 4: + break + firmware.append(struct.unpack(">I", word)[0]) + return firmware + + def main(): - top = Top() + parser = argparse.ArgumentParser() + parser.add_argument("firmware_bin") + parser.add_argument("output_file") + args = parser.parse_args() + + firmware = read_firmware(args.firmware_bin) + + top = Top(firmware) output = rtlil.convert(Fragment.get(top, None), ports=(top.clk100, top.serial_tx)) - print(output) + with open(args.output_file, "w") as f: + f.write(output) if __name__ == "__main__": main()