Skip to content

Instantly share code, notes, and snippets.

@Michaelvll
Last active November 17, 2018 05:01
Show Gist options
  • Save Michaelvll/46e069e29a8448326acadd7bb2bb1654 to your computer and use it in GitHub Desktop.
Save Michaelvll/46e069e29a8448326acadd7bb2bb1654 to your computer and use it in GitHub Desktop.
Makefile for *.s assemble to or *.cpp compile to inst_rom.mem

Usage

  1. Put the files below to the same directory of *.cpp/.c or *.s

  2. Execute make <filename>.bin. And it will generate corrsponding file inst_rom.bin containing the machine code that can be executed(for simulating memory on PC)

  3. Execute make <filename>.dmem. And it will generate corrsponding file inst_rom.mem containing the machine code that can be executed(for simulation in vivado)

  4. make <filename>.S can generate corresponding assembly file for <filename>.cpp/.c

  5. make <filename>.dump/.ddump can dump the disamssembly the mixed assembly of .cpp/.c and rom.o, system.o

Prerequest

  1. riscv tool chain
  2. python3

Reference

  1. bin2mem.py is from Evensgn的riscv tool chain教程
  2. memory.ld and rom.s are from zzk的cpu-judge
# based on Lequn Chen's Code
# by Evensgn
# modified by MW
#!/usr/bin/env python
import os
import sys
import binascii
INPUT = sys.argv[1]
OUTPUT = sys.argv[2]
STDOUTPUT = sys.argv[3]
s = open(INPUT, 'rb').read()
s = binascii.b2a_hex(s)
with open(STDOUTPUT, 'w') as f:
for i in range(0, len(s), 2):
f.write(str(s[i:i + 2])[2:-1])
f.write('\n')
with open(OUTPUT, 'w') as f:
for i in range(0, len(s), 8):
f.write(str(s[i + 6:i + 8] + s[i + 4:i + 6] +
s[i + 2:i + 4] + s[i:i + 2])[2:-1])
f.write('\n')
SECTIONS
{
. = 0x00000000;
.rom :
{
*(.rom)
}
. = 0x00001000;
.text :
{
*(.text)
}
.rodata ALIGN(4) :
{
*(.rodata)
}
.data ALIGN(4) :
{
*(.data)
}
__bss_start = .;
.bss ALIGN(4) :
{
*(.bss)
}
__bss_end = .;
__heap_start = (__bss_end + 0xfff) & 0x000ff000;
}
.section .rom,"ax"
.globl main
li sp, 0x00100000
# li sp, 0x00010000
jal main
# sw sp, -8(sp)
li a0, 0xff
sb a0, 0x108(zero)
.L0:
j .L0
# By MW
CROSS_COMPILE = riscv32-unknown-elf-
CXX = $(CROSS_COMPILE)g++
C = $(CROSS_COMPILE)gcc
CXXFLAGS = -march=rv32i -mabi=ilp32 -c -O2
CFLAGS = -march=rv32i -mabi=ilp32 -c -O2
AS = $(CROSS_COMPILE)as
AS_FLAGS = -march=rv32i
LD = $(CROSS_COMPILE)ld
LD_FLAGS = -T memory.ld -L /opt/riscv/lib/gcc/riscv32-unknown-elf/7.2.0 -L /opt/riscv/riscv32-unknown-elf/lib -lc -lgcc -lm -lnosys
DLD_FLAGS = -T dmemory.ld -L /opt/riscv/lib/gcc/riscv32-unknown-elf/7.2.0 -L /opt/riscv/riscv32-unknown-elf/lib -lc -lgcc -lm -lnosys
BIN = $(CROSS_COMPILE)objcopy
DUMP = $(CROSS_COMPILE)objdump
DUMP_FLAGS = -d
ELF = riscv32-unknown-elf
CPP_FILES = $(wildcard *.cpp)
S_FILES = $(wildcard *.[s|S])
STDNAME = inst_rom
PROGRAM = $(if $(CPP_FILES),$(basename $(CPP_FILES)),$(basename $(S_FILES)))
%.mem: %.bin
python3 ./bin2mem.py $< $@ $(STDNAME).mem
%.dump: %.om
$(DUMP) $< $(DUMP_FLAGS)
%.readelf: %.o
$(ELF) -h $<
%.dmem: %.dbin
python3 ./bin2mem.py $< $@ $(STDNAME).mem
%.dbin:%.dom
$(BIN) $< -O binary $@
cp $@ $(STDNAME).bin
%.dom: %.o drom.o system.o %.cpp
$(LD) $< drom.o system.o -o $@ $(DLD_FLAGS)
%.dom: %.o drom.o system.o %.c
$(LD) $< drom.o system.o -o $@ $(DLD_FLAGS)
drom.o:
$(AS) -o drom.o drom.s $(AS_FLAGS)
%.ddump:%.dom
$(DUMP) $< $(DUMP_FLAGS)
%.bin: %.om
$(BIN) $< -O binary $@
cp $@ $(STDNAME).bin
%.om: %.o rom.o system.o %.cpp
$(LD) $< rom.o system.o -o $@ $(LD_FLAGS)
%.om: %.o rom.o system.o %.c
$(LD) $< rom.o system.o -o $@ $(LD_FLAGS)
%.om: %.o %.s
$(LD) $< -o $@
rom.o:
$(AS) -o rom.o rom.s $(AS_FLAGS)
system.o:
$(C) -o system.o system.c $(CFLAGS)
%.o: %.c
$(C) $(CFLAGS) -o $@ $<
%.o: %.cpp
$(CXX) $(CXXFLAGS) -o $@ $<
%.o: %.s
$(AS) -o $@ $< $(AS_FLAGS)
%.S: %.cpp
$(CXX) $(CXXFLAGS) -S -o $@ $<
cleantmp:
@rm -f *.o *.om *.bin
clean:
@rm -f *.o *.om *.bin *.mem *.dmem *.dbin *.out
SECTIONS
{
. = 0x00000000;
.rom :
{
*(.rom)
}
. = 0x00001000;
.text :
{
*(.text)
}
.rodata ALIGN(4) :
{
*(.rodata)
}
.data ALIGN(4) :
{
*(.data)
}
__bss_start = .;
.bss ALIGN(4) :
{
*(.bss)
}
__bss_end = .;
__heap_start = (__bss_end + 0xfff) & 0xfffff000;
}
.section .rom,"ax"
.globl main
li sp, 0x10000000
# li sp, 0x00010000
jal main
# sw sp, -8(sp)
li a0, 0xff
sb a0, 0x108(zero)
.L0:
j .L0
// By zzk
#include <stdint.h>
#include <unistd.h>
extern int __heap_start;
static inline void out(unsigned char data) {
*((volatile unsigned char *)0x104) = data;
}
static inline unsigned int in() { return *((volatile unsigned int *)0x100); }
void *sbrk(intptr_t increment) {
static void *heap = (void *)&__heap_start;
void *start = heap;
heap += increment;
return start;
}
ssize_t write(int fd, const void *buf, size_t nbyte) {
if (fd == STDOUT_FILENO) {
const unsigned char *ptr = (const unsigned char *)buf;
size_t i;
for (i = 0; i < nbyte; i++)
out(ptr[i]);
return nbyte;
}
return -1;
}
ssize_t read(int fd, void *buf, size_t nbyte) {
if (fd == STDIN_FILENO) {
unsigned char *ptr = (unsigned char *)buf;
size_t i;
for (i = 0; i < nbyte; i++) {
unsigned int rd = in();
if (rd == ~0)
return i;
ptr[i] = (unsigned char)rd;
}
return nbyte;
}
return -1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment