diff --git a/src/main/scala/vexriscv/plugin/DecoderSimplePlugin.scala b/src/main/scala/vexriscv/plugin/DecoderSimplePlugin.scala index 12e6241..c6bf1da 100644 --- a/src/main/scala/vexriscv/plugin/DecoderSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/DecoderSimplePlugin.scala @@ -43,11 +43,23 @@ case class Masked(value : BigInt,care : BigInt){ class DecoderSimplePlugin(catchIllegalInstruction : Boolean, forceLegalInstructionComputation : Boolean = false) extends Plugin[VexRiscv] with DecoderService { override def add(encoding: Seq[(MaskedLiteral, Seq[(Stageable[_ <: BaseType], Any)])]): Unit = encoding.foreach(e => this.add(e._1,e._2)) override def add(key: MaskedLiteral, values: Seq[(Stageable[_ <: BaseType], Any)]): Unit = { - assert(!encodings.contains(key)) - encodings.getOrElseUpdate(key,ArrayBuffer[(Stageable[_ <: BaseType], BaseType)]()) ++= values.map{case (a,b) => (a,b match{ - case e : SpinalEnumElement[_] => e() - case e : BaseType => e - })} +// val instructionModel = encodings.getOrElseUpdate(key,ArrayBuffer[(Stageable[_ <: BaseType], BaseType)]()) + val instructionModel = encodings.find(x => x._1.careAbout == key.careAbout && x._1.width == key.width && x._1.value == key.value) match { + case Some(x) => x._2 + case _ => { + val model = ArrayBuffer[(Stageable[_ <: BaseType], BaseType)]() + encodings.put(key, model) + model + } + } + values.map{case (a,b) => { + assert(!instructionModel.contains(a), s"Over specification of $a") + val value = b match { + case e: SpinalEnumElement[_] => e() + case e: BaseType => e + } + instructionModel += (a->value) + }} } override def addDefault(key: Stageable[_ <: BaseType], value: Any): Unit = { diff --git a/src/test/cpp/custom/atomic/build/atomic.asm b/src/test/cpp/custom/atomic/build/atomic.asm new file mode 100644 index 0000000..e5351c8 --- /dev/null +++ b/src/test/cpp/custom/atomic/build/atomic.asm @@ -0,0 +1,44 @@ + +build/atomic.elf: file format elf32-littleriscv + + +Disassembly of section .crt_section: + +00000000 <_start>: + 0: 00100e13 li t3,1 + 4: 10000537 lui a0,0x10000 + 8: 06400593 li a1,100 + c: 06500613 li a2,101 + 10: 06600693 li a3,102 + 14: 00d52023 sw a3,0(a0) # 10000000 + 18: 18b5262f sc.w a2,a1,(a0) + 1c: 02060c63 beqz a2,54 + 20: 00052703 lw a4,0(a0) + 24: 02e69863 bne a3,a4,54 + 28: 00200e13 li t3,2 + 2c: 10000537 lui a0,0x10000 + 30: 06400593 li a1,100 + 34: 06500613 li a2,101 + 38: 06600693 li a3,102 + 3c: 00d52023 sw a3,0(a0) # 10000000 + 40: 18b5262f sc.w a2,a1,(a0) + 44: 00060863 beqz a2,54 + 48: 00052703 lw a4,0(a0) + 4c: 00e69463 bne a3,a4,54 + 50: 0100006f j 60 + +00000054 : + 54: f0100137 lui sp,0xf0100 + 58: f2410113 addi sp,sp,-220 # f00fff24 + 5c: 01c12023 sw t3,0(sp) + +00000060 : + 60: f0100137 lui sp,0xf0100 + 64: f2010113 addi sp,sp,-224 # f00fff20 + 68: 00012023 sw zero,0(sp) + 6c: 00000013 nop + 70: 00000013 nop + 74: 00000013 nop + 78: 00000013 nop + 7c: 00000013 nop + 80: 00000013 nop diff --git a/src/test/cpp/custom/atomic/build/atomic.elf b/src/test/cpp/custom/atomic/build/atomic.elf new file mode 100755 index 0000000..329fd55 Binary files /dev/null and b/src/test/cpp/custom/atomic/build/atomic.elf differ diff --git a/src/test/cpp/custom/atomic/build/atomic.hex b/src/test/cpp/custom/atomic/build/atomic.hex new file mode 100644 index 0000000..7c19430 --- /dev/null +++ b/src/test/cpp/custom/atomic/build/atomic.hex @@ -0,0 +1,10 @@ +:10000000130E100037050010930540061306500626 +:10001000930660062320D5002F26B518630C060230 +:10002000032705006398E602130E20003705001031 +:100030009305400613065006930660062320D5005C +:100040002F26B51863080600032705006394E60011 +:100050006F000001370110F0130141F22320C101AC +:10006000370110F0130101F22320010013000000FA +:100070001300000013000000130000001300000034 +:040080001300000069 +:00000001FF diff --git a/src/test/cpp/custom/atomic/build/atomic.map b/src/test/cpp/custom/atomic/build/atomic.map new file mode 100644 index 0000000..1c5a2c2 --- /dev/null +++ b/src/test/cpp/custom/atomic/build/atomic.map @@ -0,0 +1,30 @@ + +Memory Configuration + +Name Origin Length Attributes +onChipRam 0x0000000000000000 0x0000000000002000 w !xr +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + +LOAD build/src/crt.o +LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/libgcc.a +START GROUP +LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/../../../../riscv64-unknown-elf/lib/libc.a +LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/../../../../riscv64-unknown-elf/lib/libgloss.a +END GROUP +LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/libgcc.a + 0x0000000000000000 . = 0x0 + +.crt_section 0x0000000000000000 0x84 + 0x0000000000000000 . = ALIGN (0x4) + *crt.o(.text) + .text 0x0000000000000000 0x84 build/src/crt.o + 0x0000000000000000 _start +OUTPUT(build/atomic.elf elf32-littleriscv) + +.data 0x0000000000000084 0x0 + .data 0x0000000000000084 0x0 build/src/crt.o + +.bss 0x0000000000000084 0x0 + .bss 0x0000000000000084 0x0 build/src/crt.o diff --git a/src/test/cpp/custom/atomic/build/atomic.v b/src/test/cpp/custom/atomic/build/atomic.v new file mode 100755 index 0000000..f093cc9 --- /dev/null +++ b/src/test/cpp/custom/atomic/build/atomic.v @@ -0,0 +1,10 @@ +@00000000 +13 0E 10 00 37 05 00 10 93 05 40 06 13 06 50 06 +93 06 60 06 23 20 D5 00 2F 26 B5 18 63 0C 06 02 +03 27 05 00 63 98 E6 02 13 0E 20 00 37 05 00 10 +93 05 40 06 13 06 50 06 93 06 60 06 23 20 D5 00 +2F 26 B5 18 63 08 06 00 03 27 05 00 63 94 E6 00 +6F 00 00 01 37 01 10 F0 13 01 41 F2 23 20 C1 01 +37 01 10 F0 13 01 01 F2 23 20 01 00 13 00 00 00 +13 00 00 00 13 00 00 00 13 00 00 00 13 00 00 00 +13 00 00 00 diff --git a/src/test/cpp/custom/atomic/makefile b/src/test/cpp/custom/atomic/makefile new file mode 100644 index 0000000..217a057 --- /dev/null +++ b/src/test/cpp/custom/atomic/makefile @@ -0,0 +1,73 @@ +PROJ_NAME=atomic + + +RISCV_PATH=/opt/riscv/ +CFLAGS += -march=rv32ia -mabi=ilp32 +RISCV_NAME = riscv64-unknown-elf +RISCV_OBJCOPY = $(RISCV_PATH)/bin/$(RISCV_NAME)-objcopy +RISCV_OBJDUMP = $(RISCV_PATH)/bin/$(RISCV_NAME)-objdump +RISCV_CLIB=$(RISCV_PATH)$(RISCV_NAME)/lib/ +RISCV_CC=$(RISCV_PATH)/bin/$(RISCV_NAME)-gcc +LDSCRIPT=src/ld + + +SRCS = $(wildcard src/*.c) \ + $(wildcard src/*.cpp) \ + $(wildcard src/*.S) + + +CFLAGS += -static +LDFLAGS += -e_start -T $(LDSCRIPT) -nostartfiles -Wl,-Map,$(OBJDIR)/$(PROJ_NAME).map -Wl,--print-memory-usage +OBJDIR = build +OBJS := $(SRCS) +OBJS := $(OBJS:.c=.o) +OBJS := $(OBJS:.cpp=.o) +OBJS := $(OBJS:.S=.o) +OBJS := $(addprefix $(OBJDIR)/,$(OBJS)) + + + +all: $(OBJDIR)/$(PROJ_NAME).elf $(OBJDIR)/$(PROJ_NAME).hex $(OBJDIR)/$(PROJ_NAME).asm $(OBJDIR)/$(PROJ_NAME).v + @echo "done" + +$(OBJDIR)/%.elf: $(OBJS) | $(OBJDIR) + $(RISCV_CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS) + +%.hex: %.elf + $(RISCV_OBJCOPY) -O ihex $^ $@ + +%.bin: %.elf + $(RISCV_OBJCOPY) -O binary $^ $@ + +%.v: %.elf + $(RISCV_OBJCOPY) -O verilog $^ $@ + +%.asm: %.elf + $(RISCV_OBJDUMP) -S -d $^ > $@ + +$(OBJDIR)/%.o: %.c + mkdir -p $(dir $@) + $(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^ + +$(OBJDIR)/%.o: %.cpp + mkdir -p $(dir $@) + $(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^ + +$(OBJDIR)/%.o: %.S + mkdir -p $(dir $@) + $(RISCV_CC) -c $(CFLAGS) -o $@ $^ -D__ASSEMBLY__=1 + +$(OBJDIR): + mkdir -p $@ + +clean: + rm -f $(OBJDIR)/$(PROJ_NAME).elf + rm -f $(OBJDIR)/$(PROJ_NAME).hex + rm -f $(OBJDIR)/$(PROJ_NAME).map + rm -f $(OBJDIR)/$(PROJ_NAME).v + rm -f $(OBJDIR)/$(PROJ_NAME).asm + find $(OBJDIR) -type f -name '*.o' -print0 | xargs -0 -r rm + +.SECONDARY: $(OBJS) + + diff --git a/src/test/cpp/custom/atomic/src/crt.S b/src/test/cpp/custom/atomic/src/crt.S new file mode 100644 index 0000000..105c1e7 --- /dev/null +++ b/src/test/cpp/custom/atomic/src/crt.S @@ -0,0 +1,50 @@ +.globl _start +_start: + + +//Test 1 SC on unreserved area should fail and not write memory + li x28, 1 + li a0, 0x10000000 + li a1, 100 + li a2, 101 + li a3, 102 + sw a3, 0(a0) + sc.w a2, a1, (a0) + beq a2, x0, fail + lw a4, 0(a0) + bne a3, a4, fail + +//Test 2 retrying SC on unreserved area should fail and not write memory + li x28, 2 + li a0, 0x10000000 + li a1, 100 + li a2, 101 + li a3, 102 + sw a3, 0(a0) + sc.w a2, a1, (a0) + beq a2, x0, fail + lw a4, 0(a0) + bne a3, a4, fail + + + + j pass + + + +fail: //x28 => error code + li x2, 0xF00FFF24 + sw x28, 0(x2) + +pass: + li x2, 0xF00FFF20 + sw x0, 0(x2) + + + + nop + nop + nop + nop + nop + nop diff --git a/src/test/cpp/custom/atomic/src/ld b/src/test/cpp/custom/atomic/src/ld new file mode 100644 index 0000000..8d95523 --- /dev/null +++ b/src/test/cpp/custom/atomic/src/ld @@ -0,0 +1,17 @@ +OUTPUT_ARCH( "riscv" ) + +MEMORY { + onChipRam (W!RX)/*(RX)*/ : ORIGIN = 0x00000000, LENGTH = 8K +} + +SECTIONS +{ + . = 0x000; + + .crt_section : + { + . = ALIGN(4); + *crt.o(.text) + } > onChipRam + +} diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index 6259d69..1f01ee6 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -1725,6 +1725,11 @@ int main(int argc, char **argv, char **env) { redo(REDO,Workspace("custom_simd_add").loadHex("../custom/simd_add/build/custom_simd_add.hex")->bootAt(0x00000000u)->run(50e3);); #endif + + #ifdef ATOMIC + redo(REDO,Workspace("atomic").loadHex("../custom/atomic/build/atomic.hex")->bootAt(0x00000000u)->run(50e3);); + #endif + #ifdef DHRYSTONE Dhrystone("dhrystoneO3_Stall","dhrystoneO3",true,true).run(1.1e6); #if defined(MUL) && defined(DIV) diff --git a/src/test/cpp/regression/makefile b/src/test/cpp/regression/makefile index 3572e49..c56b846 100644 --- a/src/test/cpp/regression/makefile +++ b/src/test/cpp/regression/makefile @@ -8,6 +8,7 @@ MUL?=yes DIV?=yes CSR?=yes MMU?=yes +ATOMIC?=no DEBUG_PLUGIN?=STD DEBUG_PLUGIN_EXTERNAL?=no CUSTOM_SIMD_ADD?=no @@ -38,6 +39,11 @@ ifeq ($(CSR),yes) ADDCFLAGS += -CFLAGS -DCSR endif + +ifeq ($(ATOMIC),yes) + ADDCFLAGS += -CFLAGS -DATOMIC +endif + ifeq ($(CUSTOM_SIMD_ADD),yes) ADDCFLAGS += -CFLAGS -DCUSTOM_SIMD_ADD endif