Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add COE and MEM file generator options #904

Merged
merged 3 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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