Skip to content

Commit

Permalink
Add COE and MEM file generator options (#904)
Browse files Browse the repository at this point in the history
  • Loading branch information
stnolting committed May 16, 2024
2 parents 1e274bf + eb7ad79 commit 1981b40
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 78 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ __pycache__

# generated app files
*.bin
*.coe
*.mem
*.o
*.elf
*.asm
Expand Down
10 changes: 7 additions & 3 deletions docs/datasheet/software.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ Targets:
elf - compile and generate <main.elf> ELF file
bin - compile and generate <neorv32_raw_exe.bin> RAW executable file (binary file, no header)
hex - compile and generate <neorv32_raw_exe.hex> RAW executable file (hex char file, no header)
coe - compile and generate <neorv32_raw_exe.coe>> RAW executable file (COE file, no header)
mem - compile and generate <neorv32_raw_exe.mem>> RAW executable file (MEM file, no header)
image - compile and generate VHDL IMEM boot image (for application, no header) in local folder
install - compile, generate and install VHDL IMEM boot image (for application, no header)
sim - in-console simulation using default/simple testbench and GHDL
Expand Down Expand Up @@ -476,16 +478,18 @@ is available in `sw/example/demo_newlib`
==== Executable Image Generator
The `main.bin` file is packed by the NEORV32 image generator (`sw/image_gen`) to generate the final executable file.
The image generator can generate several types of executables selected by a flag when calling the generator:
The image generator can generate several types of executable file formats selected by a flag when calling the generator:
[cols="<2,<8"]
[grid="none"]
|=======================
| `-app_bin` | Generates an executable binary file `neorv32_exe.bin` (including header) for UART uploading via the bootloader.
| `-app_img` | Generates an executable VHDL memory initialization image (no header) for the processor-internal IMEM. This option generates the `rtl/core/neorv32_application_image.vhd` file.
| `-raw_hex` | Generates a plain ASCII hex-char file `neorv32_raw_exe.hex` (no header) for custom purpose.
| `-raw_bin` | Generates a plain binary file `neorv32_raw_exe.bin` (no header) for custom purpose.
| `-bld_img` | Generates an executable VHDL memory initialization image (no header) for the processor-internal BOOT ROM. This option generates the `rtl/core/neorv32_bootloader_image.vhd` file.
| `-raw_hex` | Generates a plain 8x ASCII hex-char file `neorv32_raw_exe.hex` (no header) for custom purpose.
| `-raw_bin` | Generates a plain binary file `neorv32_raw_exe.bin` (no header) for custom purpose.
| `-raw_coe` | Generates a COE file `neorv32_raw_exe.coe` (no header) for FPGA memory initialization.
| `-raw_mem` | Generates a MEM file `neorv32_raw_exe.mem` (no header) for FPGA memory initialization.
|=======================
All these options are managed by the makefile. The normal application compilation flow will generate the `neorv32_exe.bin`
Expand Down
63 changes: 27 additions & 36 deletions sw/common/common.mk
Original file line number Diff line number Diff line change
@@ -1,35 +1,12 @@
#################################################################################################
# << NEORV32 - Application Makefile >> #
# ********************************************************************************************* #
# BSD 3-Clause License #
# #
# The NEORV32 RISC-V Processor, https://github.com/stnolting/neorv32 #
# Copyright (c) 2024, Stephan Nolting. All rights reserved. #
# #
# Redistribution and use in source and binary forms, with or without modification, are #
# permitted provided that the following conditions are met: #
# #
# 1. Redistributions of source code must retain the above copyright notice, this list of #
# conditions and the following disclaimer. #
# #
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
# conditions and the following disclaimer in the documentation and/or other materials #
# provided with the distribution. #
# #
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
# endorse or promote products derived from this software without specific prior written #
# permission. #
# #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
# OF THE POSSIBILITY OF SUCH DAMAGE. #
#################################################################################################
# ================================================================================ #
# NEORV32 Software Makefile #
# -------------------------------------------------------------------------------- #
# The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 #
# Copyright (c) NEORV32 contributors. #
# Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. #
# Licensed under the BSD-3-Clause license, see LICENSE for details. #
# SPDX-License-Identifier: BSD-3-Clause #
# ================================================================================ #


# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -98,6 +75,8 @@ APP_EXE = neorv32_exe.bin
APP_ELF = main.elf
APP_HEX = neorv32_raw_exe.hex
APP_BIN = neorv32_raw_exe.bin
APP_COE = neorv32_raw_exe.coe
APP_MEM = neorv32_raw_exe.mem
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
Expand Down Expand Up @@ -156,16 +135,16 @@ NEO_ASFLAGS = $(CC_FLAGS) $(ASFLAGS)
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help

# 'compile' is still here for compatibility
asm: $(APP_ASM)
elf: $(APP_ELF)
exe: $(APP_EXE)
hex: $(APP_HEX)
bin: $(APP_BIN)
compile: $(APP_EXE)
coe: $(APP_COE)
mem: $(APP_MEM)
image: $(APP_IMG)
install: image install-$(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG) install hex bin
all: $(APP_ASM) $(APP_EXE) $(APP_HEX) $(APP_BIN) $(APP_COE) $(APP_MEM) $(APP_IMG) install hex bin

# Check if making bootloader
# Use different base address and length for instruction memory/"rom" (BOOTROM instead of IMEM)
Expand Down Expand Up @@ -252,6 +231,16 @@ $(APP_BIN): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -raw_bin $< $@ $(shell basename $(CURDIR))

# Generate NEORV32 RAW executable image in COE format
$(APP_COE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -raw_coe $< $@ $(shell basename $(CURDIR))

# Generate NEORV32 RAW executable image in MEM format
$(APP_MEM): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -raw_mem $< $@ $(shell basename $(CURDIR))


# -----------------------------------------------------------------------------
# Bootloader targets
Expand Down Expand Up @@ -325,7 +314,7 @@ gdb:
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd *.hex .gdb_history
@rm -f *.elf *.o *.bin *.coe *.mem *.out *.asm *.vhd *.hex .gdb_history

clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
Expand Down Expand Up @@ -413,6 +402,8 @@ help:
@echo " exe - compile and generate <$(APP_EXE)> executable for upload via default bootloader (binary file, with header)"
@echo " bin - compile and generate <$(APP_BIN)> RAW executable file (binary file, no header)"
@echo " hex - compile and generate <$(APP_HEX)> RAW executable file (hex char file, no header)"
@echo " coe - compile and generate <$(APP_COE)> RAW executable file (COE file, no header)"
@echo " mem - compile and generate <$(APP_MEM)> RAW executable file (MEM file, no header)"
@echo " image - compile and generate VHDL IMEM boot image (for application, no header) in local folder"
@echo " install - compile, generate and install VHDL IMEM boot image (for application, no header)"
@echo " sim - in-console simulation using default/simple testbench and GHDL"
Expand Down
120 changes: 81 additions & 39 deletions sw/image_gen/image_gen.c
Original file line number Diff line number Diff line change
@@ -1,36 +1,12 @@
// #################################################################################################
// # << NEORV32 - Executable image generator tool >> #
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2023, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
// # #
// # 1. Redistributions of source code must retain the above copyright notice, this list of #
// # conditions and the following disclaimer. #
// # #
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
// # conditions and the following disclaimer in the documentation and/or other materials #
// # provided with the distribution. #
// # #
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
// # endorse or promote products derived from this software without specific prior written #
// # permission. #
// # #
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
// # OF THE POSSIBILITY OF SUCH DAMAGE. #
// # ********************************************************************************************* #
// # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
// #################################################################################################
// ================================================================================ //
// Executable memory image generator //
// -------------------------------------------------------------------------------- //
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
// Copyright (c) NEORV32 contributors. //
// Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. //
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
// SPDX-License-Identifier: BSD-3-Clause //
// ================================================================================ //

#include <stdint.h>
#include <stdio.h>
Expand All @@ -41,7 +17,7 @@
// executable signature ("magic word")
const uint32_t signature = 0x4788CAFE;

enum operation_enum {OP_APP_BIN, OP_APP_IMG, OP_BLD_IMG, OP_RAW_HEX, OP_RAW_BIN};
enum operation_enum {OP_APP_BIN, OP_APP_IMG, OP_BLD_IMG, OP_RAW_HEX, OP_RAW_BIN, OP_RAW_COE, OP_RAW_MEM};

int main(int argc, char *argv[]) {

Expand All @@ -51,9 +27,11 @@ int main(int argc, char *argv[]) {
"1st: Operation\n"
" -app_bin : Generate application executable binary (binary file, little-endian, with header) \n"
" -app_img : Generate application raw executable memory image (vhdl package body file, no header)\n"
" -bld_img : Generate bootloader raw executable memory image (vhdl package body file, no header)\n"
" -raw_hex : Generate application raw executable (ASCII hex file, no header)\n"
" -raw_bin : Generate application raw executable (binary file, no header)\n"
" -bld_img : Generate bootloader raw executable memory image (vhdl package body file, no header)\n"
" -raw_coe : Generate application raw executable (COE file, no header)\n"
" -raw_mem : Generate application raw executable (MEM file, no header)\n"
"2nd: Input file (raw binary image)\n"
"3rd: Output file\n"
"4th: Project name or folder (optional)\n");
Expand All @@ -73,6 +51,8 @@ int main(int argc, char *argv[]) {
else if (strcmp(argv[1], "-bld_img") == 0) { operation = OP_BLD_IMG; }
else if (strcmp(argv[1], "-raw_hex") == 0) { operation = OP_RAW_HEX; }
else if (strcmp(argv[1], "-raw_bin") == 0) { operation = OP_RAW_BIN; }
else if (strcmp(argv[1], "-raw_coe") == 0) { operation = OP_RAW_COE; }
else if (strcmp(argv[1], "-raw_mem") == 0) { operation = OP_RAW_MEM; }
else {
printf("Invalid operation!");
return -1;
Expand Down Expand Up @@ -212,7 +192,7 @@ int main(int argc, char *argv[]) {
// Generate APPLICATION's executable memory initialization file (no header!)
// => VHDL package body
// --------------------------------------------------------------------------
if (operation == OP_APP_IMG) {
else if (operation == OP_APP_IMG) {

// header
sprintf(tmp_string, "-- The NEORV32 RISC-V Processor: https://github.com/stnolting/neorv32\n"
Expand Down Expand Up @@ -269,7 +249,7 @@ int main(int argc, char *argv[]) {
// Generate BOOTLOADER's executable memory initialization file (no header!)
// => VHDL package body
// --------------------------------------------------------------------------
if (operation == OP_BLD_IMG) {
else if (operation == OP_BLD_IMG) {

// header
sprintf(tmp_string, "-- The NEORV32 RISC-V Processor: https://github.com/stnolting/neorv32\n"
Expand Down Expand Up @@ -325,7 +305,7 @@ int main(int argc, char *argv[]) {
// --------------------------------------------------------------------------
// Generate raw APPLICATION's executable ASCII hex file (no header!)
// --------------------------------------------------------------------------
if (operation == OP_RAW_HEX) {
else if (operation == OP_RAW_HEX) {

while(fread(&buffer, sizeof(unsigned char), 4, input) != 0) {
tmp = (uint32_t)(buffer[0] << 0);
Expand All @@ -341,14 +321,76 @@ int main(int argc, char *argv[]) {
// --------------------------------------------------------------------------
// Generate raw APPLICATION's executable binary file (no header!)
// --------------------------------------------------------------------------
if (operation == OP_RAW_BIN) {
else if (operation == OP_RAW_BIN) {

while(fread(&buffer, sizeof(unsigned char), 1, input) != 0) {
fputc(buffer[0], output);
}
}


// --------------------------------------------------------------------------
// Generate raw APPLICATION's executable COE file (no header!)
// --------------------------------------------------------------------------
else if (operation == OP_RAW_COE) {

// header
sprintf(tmp_string, "memory_initialization_radix=16;\n");
fputs(tmp_string, output);
sprintf(tmp_string, "memory_initialization_vector=");
fputs(tmp_string, output);

i = 0;
while(fread(&buffer, sizeof(unsigned char), 4, input) != 0) {
tmp = (uint32_t)(buffer[0] << 0);
tmp |= (uint32_t)(buffer[1] << 8);
tmp |= (uint32_t)(buffer[2] << 16);
tmp |= (uint32_t)(buffer[3] << 24);
if (i == (input_words-1)) {
sprintf(tmp_string, "\n%08x", (unsigned int)tmp);
}
else {
sprintf(tmp_string, "\n%08x,", (unsigned int)tmp);
}
fputs(tmp_string, output);
i++;
}

// footer
sprintf(tmp_string, ";\n");
fputs(tmp_string, output);
}


// --------------------------------------------------------------------------
// Generate raw APPLICATION's executable MEM file (no header!)
// --------------------------------------------------------------------------
else if (operation == OP_RAW_MEM) {

i = 0;
while(fread(&buffer, sizeof(unsigned char), 4, input) != 0) {
tmp = (uint32_t)(buffer[0] << 0);
tmp |= (uint32_t)(buffer[1] << 8);
tmp |= (uint32_t)(buffer[2] << 16);
tmp |= (uint32_t)(buffer[3] << 24);
sprintf(tmp_string, "@%08x %08x\n", (unsigned int)i, (unsigned int)tmp);
fputs(tmp_string, output);
i++;
}
}


// --------------------------------------------------------------------------
// Invalid operation
// --------------------------------------------------------------------------
else {
printf("Invalid operation!");
fclose(input);
fclose(output);
return -1;
}


// --------------------------------------------------------------------------
// Done, clean up
// --------------------------------------------------------------------------
Expand Down

0 comments on commit 1981b40

Please sign in to comment.