Merge of main with the new icache and the branch predictor. I believe there is a bug in the icache with unaligned memory access. The second part of the access is incorrectly relying on the PCF being the address of the next two bytes of the instruction. However this is not always the case as the branch predictor can get the wrong target address. The icache needs to generate the +2 address internally.

This commit is contained in:
Ross Thompson 2021-03-30 23:18:20 -05:00
parent dd0b3fde59
commit 1e83810450
43 changed files with 3488 additions and 194 deletions

5
.gitignore vendored
View File

@ -16,3 +16,8 @@ wlft*
/imperas-riscv-tests/FunctionRadix.addr
/imperas-riscv-tests/ProgramMap.txt
/wally-pipelined/busybear-testgen/gdbcombined.txt
*.o
*.d
testsBP/*/*/*.elf*
testsBP/*/OBJ/*
testsBP/*/*.a

23
testsBP/crt0/Makefile Normal file
View File

@ -0,0 +1,23 @@
TARGETDIR := bin
TARGET := $(TARGETDIR)/start
ROOT := ..
LIBRARY_DIRS :=
LIBRARY_FILES :=
LINK_FLAGS := -nostartfiles
AFLAGS =-march=rv64ifd -W
CFLAGS =-march=rv64ifd -mcmodel=medany
AS=riscv64-unknown-elf-as
CC=riscv64-unknown-elf-gcc
AR=riscv64-unknown-elf-ar
all: libcrt0.a
%.o: %.s
${AS} ${AFLAGS} -c $< -o $@
libcrt0.a: start.o
${AR} -r $@ $^
clean:
rm -rf *.a *.o

213
testsBP/crt0/isr.s Normal file
View File

@ -0,0 +1,213 @@
.section .text
.global __trap_handler
.type __trap_handler, @function
__trap_handler:
# save the context of the cpu to the top of the current stack
addi sp, sp, -124
sw x1, 0x0(sp)
sw x2, 0x4(sp)
sw x3, 0x8(sp)
sw x4, 0xC(sp)
sw x5, 0x10(sp)
sw x6, 0x14(sp)
sw x7, 0x18(sp)
sw x8, 0x1C(sp)
sw x9, 0x20(sp)
sw x10, 0x24(sp)
sw x11, 0x28(sp)
sw x12, 0x2C(sp)
sw x13, 0x30(sp)
sw x14, 0x34(sp)
sw x15, 0x38(sp)
sw x16, 0x3C(sp)
sw x17, 0x40(sp)
sw x18, 0x44(sp)
sw x19, 0x48(sp)
sw x20, 0x4C(sp)
sw x21, 0x50(sp)
sw x22, 0x54(sp)
sw x23, 0x58(sp)
sw x24, 0x5C(sp)
sw x25, 0x60(sp)
sw x26, 0x64(sp)
sw x27, 0x68(sp)
sw x28, 0x6C(sp)
sw x29, 0x70(sp)
sw x30, 0x74(sp)
sw x31, 0x78(sp)
# figure out what caused the trap.
csrrw t0, mcause, x0
# mcause is {int, 31 bit exception code}
# for this implementation only the lowest 4 bits are used
srli t1, t0, 31 # interrupt flag
andi t2, t0, 0xF # 4 bit cause
slli t1, t1, 5 # shift int flag
or t1, t1, t2 # combine
slli t1, t1, 2 # multiply by 4
la t3, exception_table
add t4, t3, t1
lw t5, 0(t4)
jr t5, 0 # jump to specific ISR
# specific ISR is expected to set epc
restore_st:
# restore register from stack on exit.
lw x1, 0x0(sp)
lw x2, 0x4(sp)
lw x3, 0x8(sp)
lw x4, 0xC(sp)
lw x5, 0x10(sp)
lw x6, 0x14(sp)
lw x7, 0x18(sp)
lw x8, 0x1C(sp)
lw x9, 0x20(sp)
lw x10, 0x24(sp)
lw x11, 0x28(sp)
lw x12, 0x2C(sp)
lw x13, 0x30(sp)
lw x14, 0x34(sp)
lw x15, 0x38(sp)
lw x16, 0x3C(sp)
lw x17, 0x40(sp)
lw x18, 0x44(sp)
lw x19, 0x48(sp)
lw x20, 0x4C(sp)
lw x21, 0x50(sp)
lw x22, 0x54(sp)
lw x23, 0x58(sp)
lw x24, 0x5C(sp)
lw x25, 0x60(sp)
lw x26, 0x64(sp)
lw x27, 0x68(sp)
lw x28, 0x6C(sp)
lw x29, 0x70(sp)
lw x30, 0x74(sp)
lw x31, 0x78(sp)
addi sp, sp, 124
mret
.section .text
.type trap_instr_addr_misalign, @function
trap_instr_addr_misalign:
# fatal error, report error and halt
addi sp, sp, 4
sw ra, 0(sp)
jal fail
lw ra, 0(sp)
la t0, restore_st
jr t0, 0
.section .text
.type trap_m_ecall, @function
trap_m_ecall:
addi sp, sp, -4
sw ra, 0(sp)
# select which system call based on a7.
# for this example we will just define the following.
# not standard with linux or anything.
# 0: execute a call back function
# 1: decrease privilege by 1 (m=>s, s=>u, u=>u)
# 2: increase privilege by 1 (m=>m, s=>m, u=>s)
# check a7
li t0, 1
beq a7, t0, trap_m_decrease_privilege
li t0, 2
beq a7, t0, trap_m_increase_privilege
# call call back function if not zero
la t1, isr_m_ecall_cb_fp
lw t0, 0(t1)
beq t0, x0, trap_m_ecall_skip_cb
jalr ra, t0, 0
trap_m_ecall_skip_cb:
# modify the mepc
csrrw t0, mepc, x0
addi t0, t0, 4
csrrw x0, mepc, t0
lw ra, 0(sp)
addi sp, sp, 4
la t0, restore_st
jr t0, 0
trap_m_decrease_privilege:
# read the mstatus register
csrrw t0, mstatus, x0
# 11 => 01, and 01 => 00.
# this is accomplished by clearing bit 12 and taking the old
# bit 12 as the new bit 11.
li t3, 0x00001800
and t1, t0, t3 # isolates the bits 12 and 11.
# shift right by 1.
srli t2, t1, 1
and t2, t2, t3 # this will clear bit 10.
li t3, ~0x00001800
and t4, t0, t3
or t0, t2, t4
csrrw x0, mstatus, t0
j trap_m_ecall_skip_cb
trap_m_increase_privilege:
# read the mstatus register
csrrw t0, mstatus, x0
# 11 => 01, and 01 => 00.
# this is accomplished by setting bit 11 and taking the old
# bit 11 as the new bit 12.
li t3, 0x00000800
li t4, ~0x00000800
and t1, t0, t3
slli t2, t1, 1 # shift left by 1.
or t2, t2, t3 # bit 11 is always set.
and t1, t0, t5
or t0, t1, t2
csrrw x0, mstatus, t0
j trap_m_ecall_skip_cb
.data
exception_table:
.int trap_instr_addr_misalign
.int trap_instr_addr_misalign #trap_instr_access_fault
.int trap_instr_addr_misalign #trap_illegal_instr
.int trap_instr_addr_misalign #trap_breakpoint
.int trap_instr_addr_misalign #trap_load_addr_misalign
.int trap_instr_addr_misalign #trap_load_access_fault
.int trap_instr_addr_misalign #trap_store_addr_misalign
.int trap_instr_addr_misalign #trap_store_access_fault
.int trap_m_ecall
.int trap_m_ecall
.int restore_st
.int trap_m_ecall
.int trap_instr_addr_misalign #trap_instr_page_fault
.int trap_instr_addr_misalign #trap_load_page_fault
.int restore_st
.int trap_instr_addr_misalign #trap_store_page_fault
#.data
#interrupt_table:
.int trap_instr_addr_misalign #trap_u_software
.int trap_instr_addr_misalign #trap_s_software
.int restore_st
.int trap_instr_addr_misalign #trap_m_software
.int trap_instr_addr_misalign #trap_u_timer
.int trap_instr_addr_misalign #trap_s_timer
.int restore_st
.int trap_instr_addr_misalign #trap_m_timer
.int trap_instr_addr_misalign #trap_u_external
.int trap_instr_addr_misalign #trap_s_external
.int restore_st
.int trap_instr_addr_misalign #trap_m_external
.int restore_st
.int restore_st
.int restore_st
.int restore_st
.section .data
.global isr_m_ecall_cb_fp
isr_m_ecall_cb_fp:
.int 0

60
testsBP/crt0/start.s Normal file
View File

@ -0,0 +1,60 @@
.section .init
.global _start
.type _start, @function
_start:
# Initialize global pointer
.option push
.option norelax
1:auipc gp, %pcrel_hi(__global_pointer$)
addi gp, gp, %pcrel_lo(1b)
.option pop
li x1, 0
li x2, 0
li x4, 0
li x5, 0
li x6, 0
li x7, 0
li x8, 0
li x9, 0
li x10, 0
li x11, 0
li x12, 0
li x13, 0
li x14, 0
li x15, 0
li x16, 0
li x17, 0
li x18, 0
li x19, 0
li x20, 0
li x21, 0
li x22, 0
li x23, 0
li x24, 0
li x25, 0
li x26, 0
li x27, 0
li x28, 0
li x29, 0
li x30, 0
li x31, 0
# set the stack pointer to the top of memory
# 0x8000_0000 + 64K - 8 bytes
li sp, 0x0000FFF8
jal ra, main
jal ra, _halt
.section .text
.global _halt
.type _halt, @function
_halt:
li gp, 1
li a0, 0
ecall
j _halt

244
testsBP/linker.x Normal file
View File

@ -0,0 +1,244 @@
OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv",
"elf64-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(_start)
SEARCH_DIR("/opt/riscv/riscv64-unknown-elf/lib");
SECTIONS
{
/* Read-only sections, merged into text segment: */
/* init segment to ensure we get a consistent start routine*/
. = 0x0000000000000000;
. = ALIGN(0x0);
.init : {
*(.init)
}
_start_end = .;
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x0)); . = SEGMENT_START("text-segment", _start_end);
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
*(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
*(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
*(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
.rela.plt :
{
*(.rela.plt)
}
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) }
.iplt : { *(.iplt) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf64.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.sdata2 :
{
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
}
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }
/* Thread Local Storage sections */
.tdata :
{
PROVIDE_HIDDEN (__tdata_start = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
}
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
. = DATA_SEGMENT_RELRO_END (0, .);
.data :
{
__DATA_BEGIN__ = .;
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata :
{
__SDATA_BEGIN__ = .;
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)
*(.sdata .sdata.* .gnu.linkonce.s.*)
}
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.sbss :
{
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
}
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we do not
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
. = ALIGN(64 / 8);
. = SEGMENT_START("ldata-segment", .);
. = ALIGN(64 / 8);
__BSS_END__ = .;
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,
MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}

92
testsBP/makefile.inc Normal file
View File

@ -0,0 +1,92 @@
CEXT := c
CPPEXT := cpp
AEXT := s
SEXT := S
SRCEXT := \([$(CEXT)$(AEXT)$(SEXT)]\|$(CPPEXT)\)
OBJEXT := o
DEPEXT := d
SRCDIR := .
BUILDDIR := OBJ
LINKER := ${ROOT}/linker.x
SOURCES ?= $(shell find $(SRCDIR) -type f -regex ".*\.$(SRCEXT)" | sort)
OBJECTS := $(SOURCES:.$(CEXT)=.$(OBJEXT))
OBJECTS := $(OBJECTS:.$(AEXT)=.$(OBJEXT))
OBJECTS := $(OBJECTS:.$(SEXT)=.$(OBJEXT))
OBJECTS := $(OBJECTS:.$(CPPEXT)=.$(OBJEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(OBJECTS))
#Default Make
all: directories $(TARGET).memfile
#Remake
remake: clean all
#Make the Directories
directories:
@mkdir -p $(TARGETDIR)
@mkdir -p $(BUILDDIR)
clean:
rm -rf $(BUILDDIR) $(TARGETDIR) *.memfile *.objdump
#Needed for building additional library projects
ifdef LIBRARY_DIRS
LIBS+=${LIBRARY_DIRS:%=-L%} ${LIBRARY_FILES:%=-l%}
INC+=${LIBRARY_DIRS:%=-I%}
${LIBRARY_DIRS}:
make -C $@ -j 1
.PHONY: $(LIBRARY_DIRS) $(TARGET)
endif
#Pull in dependency info for *existing* .o files
-include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT))
#Link
$(TARGET): $(OBJECTS) $(LIBRARY_DIRS)
$(CC) $(LINK_FLAGS) -g -o $(TARGET) $(OBJECTS) ${LIBS} -T ${LINKER}
#Compile
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CEXT)
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
@$(CC) $(CFLAGS) $(INC) -MM $(SRCDIR)/$*.$(CEXT) > $(BUILDDIR)/$*.$(DEPEXT)
@cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp
@sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT)
@sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT)
@rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp
# gcc won't output dependencies for assembly files for some reason
# most asm files don't have dependencies so the echo will work for now.
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(AEXT)
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) -c -o $@ $< > $(BUILDDIR)/$*.list
@echo $@: $< > $(BUILDDIR)/$*.$(DEPEXT)
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SEXT)
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
@echo $@: $< > $(BUILDDIR)/$*.$(DEPEXT)
# C++
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CPPEXT)
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
@$(CC) $(CFLAGS) $(INC) -MM $(SRCDIR)/$*.$(CPPEXT) > $(BUILDDIR)/$*.$(DEPEXT)
@cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp
@sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT)
@sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT)
@rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp
# convert to hex
$(TARGET).memfile: $(TARGET)
@echo 'Making object dump file.'
@riscv64-unknown-elf-objdump -D $< > $<.objdump
@echo 'Making memory file'
exe2memfile0.pl $<
extractFunctionRadix.sh $<.objdump

15
testsBP/sieve/Makefile Normal file
View File

@ -0,0 +1,15 @@
TARGETDIR := sieve
TARGET := $(TARGETDIR)/$(TARGETDIR).elf
ROOT := ..
LIBRARY_DIRS := ${ROOT}/crt0
LIBRARY_FILES := crt0
LINK_FLAGS := -nostartfiles -Wl,-Map=$(TARGET).map
CFLAGS =-march=rv64ifd -Wa,-alhs -Wa,-L -mcmodel=medany -mstrict-align
CC=riscv64-unknown-elf-gcc
DA=riscv64-unknown-elf-objdump -d
include $(ROOT)/makefile.inc

101
testsBP/sieve/sieve.c Normal file
View File

@ -0,0 +1,101 @@
/*
* Filename:
*
* sieve.c
*
* Description:
*
* The Sieve of Eratosthenes benchmark, from Byte Magazine
* early 1980s, when a PC would do well to run this in 10
* seconds. This version really does count prime numbers
* but omits the numbers 1, 3 and all even numbers. The
* expected count is 1899.
*
*/
#include <sys/time.h>
#include <stdio.h>
#define SIZE 8190
//#define SIZE 8388608
double time_diff(struct timeval x , struct timeval y);
int sieve () {
unsigned char flags [SIZE + 1];
int iter;
int count;
for (iter = 1; iter <= 10; iter++)
{
int i, prime, k;
count = 0;
for (i = 0; i <= SIZE; i++)
flags [i] = 1;
for (i = 0; i <= SIZE; i++)
{
if (flags [i])
{
prime = i + i + 3;
k = i + prime;
while (k <= SIZE)
{
flags [k] = 0;
k += prime;
}
count++;
}
}
}
return count;
}
int main () {
int ans;
//struct timeval before , after;
//gettimeofday(&before , NULL);
ans = sieve ();
//gettimeofday(&after , NULL);
if (ans != 1899)
printf ("Sieve result wrong, ans = %d, expected 1899", ans);
//printf("Total time elapsed : %.0lf us\n" , time_diff(before , after) );
printf("Round 2\n");
//gettimeofday(&before , NULL);
ans = sieve ();
//gettimeofday(&after , NULL);
if (ans != 1899)
printf ("Sieve result wrong, ans = %d, expected 1899", ans);
//printf("Total time elapsed : %.0lf us\n" , time_diff(before , after) );
return 0;
}
double time_diff(struct timeval x , struct timeval y)
{
double x_ms , y_ms , diff;
x_ms = (double)x.tv_sec*1000000 + (double)x.tv_usec;
y_ms = (double)y.tv_sec*1000000 + (double)y.tv_usec;
diff = (double)y_ms - (double)x_ms;
return diff;
}

15
testsBP/simple/Makefile Normal file
View File

@ -0,0 +1,15 @@
TARGETDIR := simple
TARGET := $(TARGETDIR)/$(TARGETDIR).elf
ROOT := ..
LIBRARY_DIRS := ${ROOT}/crt0
LIBRARY_FILES := crt0
LINK_FLAGS := -nostartfiles -Wl,-Map=$(TARGET).map
CFLAGS =-march=rv64ifd -Wa,-alhs -Wa,-L -mcmodel=medany -mstrict-align
CC=riscv64-unknown-elf-gcc
DA=riscv64-unknown-elf-objdump -d
include $(ROOT)/makefile.inc

11
testsBP/simple/fail.s Normal file
View File

@ -0,0 +1,11 @@
# Ross Thompson
# March 17, 2021
# Oklahoma State University
.section .text
.global fail
.type fail, @function
fail:
li gp, 1
li a0, -1
ecall

6
testsBP/simple/header.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __header
#define __header
int fail();
int simple_csrbr_test();
#endif

10
testsBP/simple/main.c Normal file
View File

@ -0,0 +1,10 @@
#include "header.h"
int main(){
int res = simple_csrbr_test();
if (res < 0) {
fail();
return 0;
}else
return 0;
}

61
testsBP/simple/sample.s Normal file
View File

@ -0,0 +1,61 @@
.section .text
.global simple_csrbr_test
.type simple_csrbr_test, @function
simple_csrbr_test:
# step 1 enable the performance counters
# by default the hardware enables all performance counters
# however we will eventually want to manually enable incase
# some other code disables them
# br count is counter 5
# br mp count is counter 4
li t0, 0x30
csrrc x0, 0x320, t0 # clear bits 4 and 5 of inhibit register.
# step 2 read performance counters into general purpose registers
csrrw t2, 0xB05, x0 # t2 = BR COUNT (perf count 5)
csrrw t3, 0xB04, x0 # t3 = BRMP COUNT (perf count 4)
# step 3 simple loop to show the counters are updated.
li t0, 0 # this is the loop counter
li t1, 100 # this is the loop end condition
# for(t1 = 0; t1 < t0; t1++);
loop:
addi t0, t0, 1
blt t0, t1, loop
loop_done:
# step 2 read performance counters into general purpose registers
csrrw t4, 0xB05, x0 # t4 = BR COUNT (perf count 5)
csrrw t5, 0xB04, x0 # t5 = BRMP COUNT (perf count 4)
sub t2, t4, t2 # this is the number of branch instructions committed.
sub t3, t5, t3 # this is the number of branch mispredictions committed.
# now check if the branch count equals 100 and if the branch
bne t4, t2, fail
li t5, 3
bne t3, t5, fail
pass:
li a0, 0
done:
li t0, 0x30
csrrs x0, 0x320, t0 # set bits 4 and 5
ret
fail:
li a0, -1
j done
.data
sample_data:
.int 0

View File

@ -43,43 +43,48 @@ for(my $i=0; $i<=$#ARGV; $i++) {
my $address;
# initialize to all zeros;
# *** need to fix the zeroing range. Not always 64K
for (my $i=0; $i < 65536*4; $i++) {
$memfilebytes[$i] = "00";
}
while(<FILE>) {
if ($mode == 0) { # Parse code
# print("Examining $_\n");
if (/^\s*(\S\S\S\S\S\S\S\S):\s+(\S+)\s+/) {
# print("Examining $_\n");
if (/^\s*(\S{1,16}):\s+(\S+)\s+/) {
$address = &fixadr($1);
my $instr = $2;
my $len = length($instr);
for (my $i=0; $i<$len/2; $i++) {
$memfilebytes[$address+$i] = substr($instr, $len-2-2*$i, 2);
}
# print ("address $address $instr\n");
}
if (/Disassembly of section .data:/) { $mode = 1;}
# print ("address $address $instr\n");
}
if (/Disassembly of section .data:/) { $mode = 1;}
} elsif ($mode == 1) { # Parse data segment
if (/^\s*(\S\S\S\S\S\S\S\S):\s+(.*)/) {
if (/^\s*(\S{1,16}):\s+(.*)/) {
$address = &fixadr($1);
# print "addresss $address maxaddress $maxaddress\n";
if ($address > $maxaddress) { $maxaddress = $address; }
# print "addresss $address maxaddress $maxaddress\n";
if ($address > $maxaddress) { $maxaddress = $address; }
my $line = $2;
# merge chunks with spaces
# *** might need to change
$line =~ s/(\S)\s(\S)/$1$2/g;
# strip off comments
$line =~ /^(\S*)/;
$payload = $1;
&emitData($address, $payload);
}
if (/Disassembly of section .riscv.attributes:/) { $mode = 2; }
if (/Disassembly of section .comment:/) { $mode = 2; }
} elsif ($mode == 2) { # parse the comment section
if (/Disassembly of section .riscv.attributes:/) { $mode = 3; }
}
}
close(FILE);
$maxaddress += 32; # pad some zeros at the end
# print to memory file
# *** this is a problem
if ($fname =~ /rv32/) {
open(MEMFILE, ">$memfile") || die("Can't write $memfile");
for (my $i=0; $i<= $maxaddress; $i = $i + 4) {
@ -133,7 +138,8 @@ sub emitData {
sub fixadr {
# strip off leading 8 from address and convert to decimal
# if the leading 8 is not present don't remove.
my $adr = shift;
if ($adr =~ s/^8/0/) { return hex($adr); }
else { die("address $adr lacks leading 8\n"); }
else { return hex($adr) }
}

View File

@ -0,0 +1,145 @@
#!/usr/bin/perl -w
# exe2memfile.pl
# David_Harris@hmc.edu 26 November 2020
# Converts an executable file to a series of 32-bit hex instructions
# to read into a Verilog simulation with $readmemh
use File::stat;
use IO::Handle;
if ($#ARGV == -1) {
die("Usage: $0 executable_file");
}
# array to hold contents of memory file
my @memfilebytes = (0)*16384*4;
my $maxaddress = 0;
STDOUT->autoflush(1);
# *** Ross Thompson I think there is a bug here needs to be +1
print ("Processing $#ARGV memfiles: ");
my $frac = $#ARGV/10;
for(my $i=0; $i<=$#ARGV; $i++) {
if ($i < 10 || $i % $frac == 0) { print ("$i ") };
my $fname = $ARGV[$i];
# print "fname = $fname";
my $ofile = $fname.".objdump";
my $memfile = $fname.".memfile";
my $needsprocessing = 0;
if (!-e $memfile) { $needsprocessing = 1; } # create memfile if it doesn't exist
else {
my $osb = stat($ofile) || die("Can't stat $ofile");
my $msb = stat($memfile) || die("Can't stat $memfile");
my $otime = $osb->mtime;
my $mtime = $msb->mtime;
if ($otime > $mtime) { $needsprocessing = 1; } # is memfile out of date?
}
if ($needsprocessing == 1) {
open(FILE, $ofile) || die("Can't read $ofile");
my $mode = 0; # parse for code
my $address;
# initialize to all zeros;
# *** need to fix the zeroing range. Not always 64K
for (my $i=0; $i < 65536*4; $i++) {
$memfilebytes[$i] = "00";
}
while(<FILE>) {
# *** this mode stuff does not work if a section is missing or reordered.
if ($mode == 0) { # Parse code
# print("Examining $_\n");
if (/^\s*(\S{1,16}):\s+(\S+)\s+/) {
$address = &fixadr($1);
my $instr = $2;
my $len = length($instr);
for (my $i=0; $i<$len/2; $i++) {
$memfilebytes[$address+$i] = substr($instr, $len-2-2*$i, 2);
}
# print ("address $address $instr\n");
}
if (/Disassembly of section .data:/) { $mode = 1;}
} elsif ($mode == 1) { # Parse data segment
if (/^\s*(\S{1,16}):\s+(.*)/) {
$address = &fixadr($1);
# print "addresss $address maxaddress $maxaddress\n";
if ($address > $maxaddress) { $maxaddress = $address; }
my $line = $2;
# merge chunks with spaces
# *** might need to change
$line =~ s/(\S)\s(\S)/$1$2/g;
# strip off comments
$line =~ /^(\S*)/;
$payload = $1;
&emitData($address, $payload);
}
if (/Disassembly of section .comment:/) { $mode = 2; }
} elsif ($mode == 2) { # parse the comment section
if (/Disassembly of section .riscv.attributes:/) { $mode = 3; }
}
}
close(FILE);
$maxaddress += 32; # pad some zeros at the end
# print to memory file
# *** this is a problem
if ($fname =~ /rv32/) {
open(MEMFILE, ">$memfile") || die("Can't write $memfile");
for (my $i=0; $i<= $maxaddress; $i = $i + 4) {
for ($j=3; $j>=0; $j--) {
print MEMFILE "$memfilebytes[$i+$j]";
}
print MEMFILE "\n";
}
close(MEMFILE);
} else {
open(MEMFILE, ">$memfile") || die("Can't write $memfile");
for (my $i=0; $i<= $maxaddress; $i = $i + 8) {
for ($j=7; $j>=0; $j--) {
print MEMFILE "$memfilebytes[$i+$j]";
}
print MEMFILE "\n";
}
close(MEMFILE);
}
}
}
print("\n");
sub emitData {
# print the data portion of the ELF into a memroy file, including 0s for empty stuff
# deal with endianness
my $address = shift;
my $payload = shift;
# print("Emitting data. address = $address payload = $payload\n");
my $len = length($payload);
if ($len <= 8) {
# print word or halfword
for(my $i=0; $i<$len/2; $i++) {
my $adr = $address+$i;
my $b = substr($payload, $len-2-2*$i, 2);
$memfilebytes[$adr] = $b;
# print(" $adr $b\n");
}
} elsif ($len == 12) {
# weird case of three halfwords on line
&emitData($address, substr($payload, 0, 4));
&emitData($address+2, substr($payload, 4, 4));
&emitData($address+4, substr($payload, 8, 4));
} else {
&emitData($address, substr($payload, 0, 8));
&emitData($address+4, substr($payload, 8, $len-8));
}
}
sub fixadr {
# strip off leading 8 from address and convert to decimal
# if the leading 8 is not present don't remove.
my $adr = shift;
return hex($adr);
}

View File

@ -99,3 +99,4 @@
`define TWO_BIT_PRELOAD "../config/busybear/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/busybear/BTBPredictor.txt"
`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE
`define TESTSBP 0

View File

@ -101,3 +101,4 @@
`define TWO_BIT_PRELOAD "../config/coremark/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/coremark/BTBPredictor.txt"
`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE
`define TESTSBP 0

View File

@ -98,3 +98,4 @@
`define TWO_BIT_PRELOAD "../config/coremark_bare/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/coremark_bare/BTBPredictor.txt"
`define BPTYPE "BPGSHARE"
`define TESTSBP 0

View File

@ -95,3 +95,4 @@
`define TWO_BIT_PRELOAD "../config/rv32ic/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/rv32ic/BTBPredictor.txt"
`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE
`define TESTSBP 0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,101 @@
//////////////////////////////////////////
// wally-config.vh
//
// Written: David_Harris@hmc.edu 4 January 2021
// Modified: Brett Mathis
//
// Purpose: Specify which features are configured
// Macros to determine which modes are supported based on MISA
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
// RV32 or RV64: XLEN = 32 or 64
`define XLEN 64
//`define MISA (32'h00000104)
`define MISA (32'h00000104 | 1<<5 | 1<<18 | 1 << 20)
`define A_SUPPORTED ((`MISA >> 0) % 2 == 1)
`define C_SUPPORTED ((`MISA >> 2) % 2 == 1)
`define D_SUPPORTED ((`MISA >> 3) % 2 == 1)
`define F_SUPPORTED ((`MISA >> 5) % 2 == 1)
`define M_SUPPORTED ((`MISA >> 12) % 2 == 1)
`define S_SUPPORTED ((`MISA >> 18) % 2 == 1)
`define U_SUPPORTED ((`MISA >> 20) % 2 == 1)
`define ZCSR_SUPPORTED 1
`define COUNTERS 31
`define ZCOUNTERS_SUPPORTED 1
// N-mode user-level interrupts are depricated per Andrew Waterman 1/13/21
//`define N_SUPPORTED ((MISA >> 13) % 2 == 1)
`define N_SUPPORTED 0
`define M_MODE (2'b11)
`define S_MODE (2'b01)
`define U_MODE (2'b00)
// Microarchitectural Features
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
`define MEM_DCACHE 0
`define MEM_DTIM 1
`define MEM_ICACHE 0
`define MEM_VIRTMEM 0
// Address space
`define RESET_VECTOR 64'h0000000000000000
// Bus Interface width
`define AHBW 64
// Peripheral Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
`define BOOTTIMBASE 32'h00080000
`define BOOTTIMRANGE 32'h00003FFF
`define TIMBASE 32'h00000000
`define TIMRANGE 32'h0007FFFF
`define CLINTBASE 32'h02000000
`define CLINTRANGE 32'h0000FFFF
`define GPIOBASE 32'h10012000
`define GPIORANGE 32'h000000FF
`define UARTBASE 32'h10000000
`define UARTRANGE 32'h00000007
`define PLICBASE 32'h0C000000
`define PLICRANGE 32'h03FFFFFF
// Test modes
// Tie GPIO outputs back to inputs
`define GPIO_LOOPBACK_TEST 0
// Busybear special CSR config to match OVPSim
`define OVPSIM_CSR_CONFIG 0
// Hardware configuration
`define UART_PRESCALE 1
/* verilator lint_off STMTDLY */
/* verilator lint_off WIDTH */
/* verilator lint_off ASSIGNDLY */
/* verilator lint_off PINCONNECTEMPTY */
`define TWO_BIT_PRELOAD "../config/rv64icfd/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/rv64icfd/BTBPredictor.txt"
`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE
`define TESTSBP 1

View File

@ -0,0 +1,31 @@
//////////////////////////////////////////
// wally-constants.vh
//
// Written: tfleming@hmc.edu 4 March 2021
// Modified:
//
// Purpose: Specify certain constants defined in the RISC-V 64-bit architecture.
// These macros should not be changed, except in the event of an
// update to the architecture or particularly special circumstances.
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
// Virtual Memory Constants (sv39)
`define VPN_BITS 27
`define PPN_BITS 44
`define PA_BITS 56

View File

@ -98,3 +98,4 @@
`define TWO_BIT_PRELOAD "../config/rv64ic/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/rv64ic/BTBPredictor.txt"
`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE
`define TESTSBP 0

View File

@ -98,3 +98,4 @@
`define TWO_BIT_PRELOAD "../config/rv64icfd/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/rv64icfd/BTBPredictor.txt"
`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE
`define TESTSBP 0

View File

@ -4,55 +4,85 @@ add wave -noupdate /testbench/clk
add wave -noupdate /testbench/reset
add wave -noupdate /testbench/test
add wave -noupdate -radix ascii /testbench/memfilename
add wave -noupdate -expand -group {Execution Stage} /testbench/functionRadix/function_radix/FunctionName
add wave -noupdate -expand -group {Execution Stage} /testbench/FunctionName/FunctionName/FunctionName
add wave -noupdate -expand -group {Execution Stage} /testbench/dut/hart/ifu/PCE
add wave -noupdate -expand -group {Execution Stage} /testbench/InstrEName
add wave -noupdate -expand -group {Execution Stage} /testbench/dut/hart/ifu/InstrE
add wave -noupdate -group HDU -expand -group traps /testbench/dut/hart/priv/trap/InstrMisalignedFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/hart/priv/trap/InstrAccessFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/hart/priv/trap/IllegalInstrFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/hart/priv/trap/BreakpointFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/hart/priv/trap/LoadMisalignedFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/hart/priv/trap/StoreMisalignedFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/hart/priv/trap/LoadAccessFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/hart/priv/trap/StoreAccessFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/hart/priv/trap/EcallFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/hart/priv/trap/InstrPageFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/hart/priv/trap/LoadPageFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/hart/priv/trap/StorePageFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/hart/priv/trap/InterruptM
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/hzu/BPPredWrongE
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/hzu/CSRWritePendingDEM
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/hzu/RetM
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/hzu/TrapM
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/hzu/LoadStallD
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/hzu/InstrStall
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/hzu/DataStall
add wave -noupdate -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/hzu/FlushF
add wave -noupdate -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushD
add wave -noupdate -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushE
add wave -noupdate -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushM
add wave -noupdate -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushW
add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallF
add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallD
add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InstrMisalignedFaultM
add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InstrAccessFaultM
add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/IllegalInstrFaultM
add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/BreakpointFaultM
add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/LoadMisalignedFaultM
add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/StoreMisalignedFaultM
add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/LoadAccessFaultM
add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/StoreAccessFaultM
add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/EcallFaultM
add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InstrPageFaultM
add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/LoadPageFaultM
add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/StorePageFaultM
add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InterruptM
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/BPPredWrongE
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/CSRWritePendingDEM
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/RetM
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/TrapM
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/LoadStallD
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/InstrStall
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/DataStall
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/hzu/FlushF
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushD
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushE
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushM
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushW
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallF
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallD
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/ifu/StallE
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/ifu/StallM
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/ifu/StallW
add wave -noupdate -group Bpred -expand -group direction -color Yellow /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/GHRF
add wave -noupdate -group Bpred -expand -group direction -divider Lookup
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/LookUpPC
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/LookUpPCIndex
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/PredictionMemory
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/Prediction
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/BPPredF
add wave -noupdate -group Bpred -expand -group direction -expand -group output /testbench/dut/hart/ifu/bpred/BPPredPCF
add wave -noupdate -group Bpred -expand -group direction -expand -group output /testbench/dut/hart/ifu/bpred/SelBPPredF
add wave -noupdate -group Bpred -expand -group direction -divider Update
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/UpdatePC
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/UpdatePCIndex
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/UpdateEN
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/UpdatePrediction
add wave -noupdate -group Bpred -expand -group direction -group other /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/DoForwarding
add wave -noupdate -group Bpred -expand -group direction -group other /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/DoForwardingF
add wave -noupdate -group Bpred -expand -group direction -group other /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/GHRD
add wave -noupdate -group Bpred -expand -group direction -group other /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/GHRE
add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/hart/ifu/bpred/TargetWrongE
add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/hart/ifu/bpred/FallThroughWrongE
add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/hart/ifu/bpred/PredictionDirWrongE
add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/hart/ifu/bpred/PredictionPCWrongE
add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/hart/ifu/bpred/BPPredWrongE
add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/hart/ifu/bpred/InstrClassE
add wave -noupdate -group Bpred -group BTB -divider Update
add wave -noupdate -group Bpred -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdateEN
add wave -noupdate -group Bpred -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdatePC
add wave -noupdate -group Bpred -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdateTarget
add wave -noupdate -group Bpred -group BTB -divider Lookup
add wave -noupdate -group Bpred -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/TargetPC
add wave -noupdate -group Bpred -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/Valid
add wave -noupdate -group Bpred -group {bp wrong} -divider pcs
add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/hart/ifu/bpred/PCD
add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/hart/ifu/bpred/PCTargetE
add wave -noupdate -group Bpred -expand -group BTB -divider Update
add wave -noupdate -group Bpred -expand -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdateEN
add wave -noupdate -group Bpred -expand -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdatePC
add wave -noupdate -group Bpred -expand -group BTB /testbench/dut/hart/ifu/bpred/InstrClassE
add wave -noupdate -group Bpred -expand -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdateTarget
add wave -noupdate -group Bpred -expand -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdatePCIndexQ
add wave -noupdate -group Bpred -expand -group BTB -divider Lookup
add wave -noupdate -group Bpred -expand -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/TargetPC
add wave -noupdate -group Bpred -expand -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/InstrClass
add wave -noupdate -group Bpred -expand -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/Valid
add wave -noupdate -group Bpred /testbench/dut/hart/ifu/bpred/BPPredWrongE
add wave -noupdate -group Bpred -expand -group RAS /testbench/dut/hart/ifu/bpred/RASPredictor/pop
add wave -noupdate -group Bpred -expand -group RAS /testbench/dut/hart/ifu/bpred/RASPredictor/push
add wave -noupdate -group Bpred -expand -group RAS /testbench/dut/hart/ifu/bpred/RASPredictor/pushPC
add wave -noupdate -group Bpred -expand -group RAS /testbench/dut/hart/ifu/bpred/RASPredictor/PtrD
add wave -noupdate -group Bpred -expand -group RAS /testbench/dut/hart/ifu/bpred/RASPredictor/PtrQ
add wave -noupdate -group Bpred -expand -group RAS /testbench/dut/hart/ifu/bpred/RASPredictor/memory
add wave -noupdate -group Bpred -expand -group RAS /testbench/dut/hart/ifu/bpred/RASPredictor/popPC
add wave -noupdate -expand -group {instruction pipeline} /testbench/dut/hart/ifu/InstrF
add wave -noupdate -expand -group {instruction pipeline} /testbench/dut/hart/ifu/InstrD
add wave -noupdate -expand -group {instruction pipeline} /testbench/dut/hart/ifu/InstrE
@ -66,12 +96,12 @@ add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PCNext1F
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/SelBPPredF
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/BPPredWrongE
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PrivilegedChangePCM
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ifu/InstrD
add wave -noupdate -group {Decode Stage} /testbench/InstrDName
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/c/RegWriteD
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/RdD
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/Rs1D
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/Rs2D
add wave -noupdate -expand -group {Decode Stage} /testbench/dut/hart/ifu/InstrD
add wave -noupdate -expand -group {Decode Stage} /testbench/InstrDName
add wave -noupdate -expand -group {Decode Stage} /testbench/dut/hart/ieu/c/RegWriteD
add wave -noupdate -expand -group {Decode Stage} /testbench/dut/hart/ieu/dp/RdD
add wave -noupdate -expand -group {Decode Stage} /testbench/dut/hart/ieu/dp/Rs1D
add wave -noupdate -expand -group {Decode Stage} /testbench/dut/hart/ieu/dp/Rs2D
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/rf
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/a1
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/a2
@ -82,7 +112,6 @@ add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/we3
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/wd3
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ALUResultW
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ReadDataW
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/PCLinkW
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/CSRReadValW
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ResultSrcW
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ResultW
@ -99,10 +128,10 @@ add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/neg
add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/lt
add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/ltu
add wave -noupdate /testbench/InstrFName
add wave -noupdate -expand -group dcache /testbench/dut/hart/MemAdrM
add wave -noupdate -expand -group dcache /testbench/dut/hart/MemPAdrM
add wave -noupdate -expand -group dcache /testbench/dut/hart/WriteDataM
add wave -noupdate -expand -group dcache /testbench/dut/hart/dmem/MemRWM
add wave -noupdate -group dcache /testbench/dut/hart/MemAdrM
add wave -noupdate -group dcache /testbench/dut/hart/MemPAdrM
add wave -noupdate -group dcache /testbench/dut/hart/WriteDataM
add wave -noupdate -group dcache /testbench/dut/hart/dmem/MemRWM
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs1D
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs2D
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs1E
@ -126,23 +155,29 @@ add wave -noupdate -expand -group PCS /testbench/dut/hart/ifu/PCD
add wave -noupdate -expand -group PCS /testbench/dut/hart/PCE
add wave -noupdate -expand -group PCS /testbench/dut/hart/PCM
add wave -noupdate -expand -group PCS /testbench/PCW
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/FunctionAddr
add wave -noupdate -group {function radix debug} -radix unsigned /testbench/functionRadix/function_radix/ProgramAddrIndex
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/reset
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/ProgramLabelMapLineCount
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/ProgramLabelMapLine
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/ProgramLabelMapFP
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/ProgramLabelMapFile
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/ProgramAddrMapLineCount
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/ProgramAddrMapLine
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/ProgramAddrMapFP
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/ProgramAddrMapFile
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/pc
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/FunctionAddr
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/ProgramAddrIndex
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/FunctionName
add wave -noupdate -group {function radix debug} /testbench/FunctionName/FunctionName/FunctionAddr
add wave -noupdate -group {function radix debug} -radix unsigned /testbench/FunctionName/FunctionName/ProgramAddrIndex
add wave -noupdate -group {function radix debug} /testbench/FunctionName/FunctionName/reset
add wave -noupdate -group {function radix debug} /testbench/FunctionName/FunctionName/ProgramLabelMapLineCount
add wave -noupdate -group {function radix debug} /testbench/FunctionName/FunctionName/ProgramLabelMapLine
add wave -noupdate -group {function radix debug} /testbench/FunctionName/FunctionName/ProgramLabelMapFP
add wave -noupdate -group {function radix debug} /testbench/FunctionName/FunctionName/ProgramLabelMapFile
add wave -noupdate -group {function radix debug} /testbench/FunctionName/FunctionName/ProgramAddrMapLineCount
add wave -noupdate -group {function radix debug} /testbench/FunctionName/FunctionName/ProgramAddrMapLine
add wave -noupdate -group {function radix debug} /testbench/FunctionName/FunctionName/ProgramAddrMapFP
add wave -noupdate -group {function radix debug} /testbench/FunctionName/FunctionName/ProgramAddrMapFile
add wave -noupdate -group {function radix debug} /testbench/FunctionName/FunctionName/FunctionAddr
add wave -noupdate -group {function radix debug} /testbench/FunctionName/FunctionName/ProgramAddrIndex
add wave -noupdate -group {function radix debug} /testbench/FunctionName/FunctionName/FunctionName
add wave -noupdate -expand -group {performance counters} /testbench/dut/hart/priv/csr/genblk1/counters/MCOUNTEN
add wave -noupdate -expand -group {performance counters} /testbench/dut/hart/priv/csr/genblk1/counters/MCOUNTINHIBIT_REGW
add wave -noupdate -expand -group {performance counters} /testbench/dut/hart/priv/csr/genblk1/counters/genblk1/HPMCOUNTER_REGW
add wave -noupdate /testbench/dut/hart/ieu/dp/ALUResultW
add wave -noupdate /testbench/dut/hart/ieu/dp/ResultSrcW
add wave -noupdate /testbench/dut/hart/ieu/dp/CSRReadValW
add wave -noupdate /testbench/dut/hart/priv/csr/genblk1/counters/CSRCReadValM
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 2} {3758805 ns} 0}
WaveRestoreCursors {{Cursor 7} {13518 ns} 0}
quietly wave cursor active 1
configure wave -namecolwidth 250
configure wave -valuecolwidth 229
@ -158,4 +193,4 @@ configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ns
update
WaveRestoreZoom {1644110 ns} {15262484 ns}
WaveRestoreZoom {13489 ns} {13607 ns}

View File

@ -115,9 +115,6 @@ module datapath (
flopenrc #(`XLEN) ALUResultWReg(clk, reset, FlushW, ~StallW, ALUResultM, ALUResultW);
flopenrc #(5) RdWEg(clk, reset, FlushW, ~StallW, RdM, RdW);
// *** something is not right here. Before the merge I found an issue with the jal instruction not writing
// the link address through the alu.
// not sure what changed.
// handle Store Conditional result if atomic extension supported
generate
if (`A_SUPPORTED)

View File

@ -33,20 +33,24 @@ module BTBPredictor
)
(input logic clk,
input logic reset,
input logic StallF, StallD, StallE, FlushF, FlushD, FlushE,
input logic [`XLEN-1:0] LookUpPC,
output logic [`XLEN-1:0] TargetPC,
output logic [3:0] InstrClass,
output logic [4:0] InstrClass,
output logic Valid,
// update
input logic UpdateEN,
input logic [`XLEN-1:0] UpdatePC,
input logic [`XLEN-1:0] UpdateTarget,
input logic [3:0] UpdateInstrClass
input logic [3:0] UpdateInstrClass,
input logic UpdateInvalid
);
localparam TotalDepth = 2 ** Depth;
logic [TotalDepth-1:0] ValidBits;
logic [Depth-1:0] LookUpPCIndex, UpdatePCIndex, LookUpPCIndexQ, UpdatePCIndexQ;
logic UpdateENQ;
// hashing function for indexing the PC
// We have Depth bits to index, but XLEN bits as the input.
@ -58,7 +62,7 @@ module BTBPredictor
flopenr #(Depth) UpdatePCIndexReg(.clk(clk),
.reset(reset),
.en(1'b1),
.en(~StallE),
.d(UpdatePCIndex),
.q(UpdatePCIndexQ));
@ -66,32 +70,53 @@ module BTBPredictor
always_ff @ (posedge clk) begin
if (reset) begin
ValidBits <= #1 {TotalDepth{1'b0}};
end else if (UpdateEN) begin
ValidBits[UpdatePCIndexQ] <= #1 1'b1;
end else
if (UpdateENQ) begin
ValidBits[UpdatePCIndexQ] <= #1 ~ UpdateInvalid;
end
end
assign Valid = ValidBits[LookUpPCIndexQ];
/* -----\/----- EXCLUDED -----\/-----
regfile2p1r1w #(10, 1) validMem(.clk(clk),
.reset(reset),
.RA1(LookUpPCIndexQ),
.RD1(Valid),
.REN1(1'b1),
.WA1(UpdatePCIndexQ),
.WD1(1'b1),
.WEN1(UpdateEN));
-----/\----- EXCLUDED -----/\----- */
flopenr #() UpdateENReg(.clk(clk),
.reset(reset),
.en(~StallF),
.d(UpdateEN),
.q(UpdateENQ));
flopenr #(Depth) LookupPCIndexReg(.clk(clk),
.reset(reset),
.en(1'b1),
.en(~StallF),
.d(LookUpPCIndex),
.q(LookUpPCIndexQ));
assign Valid = ValidBits[LookUpPCIndexQ];
// the BTB contains the target address.
// Another optimization may be using a PC relative address.
// *** need to add forwarding.
SRAM2P1R1W #(Depth, `XLEN+4) memory(.clk(clk),
SRAM2P1R1W #(Depth, `XLEN+5) memory(.clk(clk),
.reset(reset),
.RA1(LookUpPCIndex),
.RD1({{InstrClass, TargetPC}}),
.REN1(1'b1),
.REN1(~StallF),
.WA1(UpdatePCIndex),
.WD1({UpdateInstrClass, UpdateTarget}),
.WEN1(UpdateEN),
.BitWEN1({4'b0000, {`XLEN{1'b1}}})); // *** definitely not right.
.BitWEN1({5'h1F, {`XLEN{1'b1}}})); // *** definitely not right.
endmodule

View File

@ -42,7 +42,7 @@ module RASPredictor
logic CounterEn;
localparam Depth = $clog2(StackSize);
logic [StackSize-1:0] PtrD, PtrQ, PtrP1, PtrM1;
logic [Depth-1:0] PtrD, PtrQ, PtrP1, PtrM1;
logic [StackSize-1:0] [`XLEN-1:0] memory;
integer index;

View File

@ -47,7 +47,7 @@ module bpred
input logic [`XLEN-1:0] PCTargetE, // The branch destination if the branch is taken.
input logic [`XLEN-1:0] PCD, // The address the branch predictor took.
input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
input logic [3:0] InstrClassE,
input logic [4:0] InstrClassE,
// Report branch prediction status
output logic BPPredWrongE
);
@ -55,12 +55,14 @@ module bpred
logic BTBValidF;
logic [1:0] BPPredF, BPPredD, BPPredE, UpdateBPPredE;
logic [3:0] BPInstrClassF, BPInstrClassD, BPInstrClassE;
logic [4:0] BPInstrClassF, BPInstrClassD, BPInstrClassE;
logic [`XLEN-1:0] BTBPredPCF, RASPCF;
logic TargetWrongE;
logic FallThroughWrongE;
logic PredictionDirWrongE;
logic PredictionPCWrongE;
logic PredictionInstrClassWrongE;
logic [`XLEN-1:0] CorrectPCE;
@ -74,7 +76,7 @@ module bpred
.Prediction(BPPredF),
// update
.UpdatePC(PCE),
.UpdateEN(InstrClassE[0]),
.UpdateEN(InstrClassE[0] & ~StallE),
.UpdatePrediction(UpdateBPPredE));
end else if (`BPTYPE == "BPGLOBAL") begin:Predictor
@ -86,7 +88,7 @@ module bpred
.Prediction(BPPredF),
// update
.UpdatePC(PCE),
.UpdateEN(InstrClassE[0]),
.UpdateEN(InstrClassE[0] & ~StallE),
.PCSrcE(PCSrcE),
.UpdatePrediction(UpdateBPPredE));
end else if (`BPTYPE == "BPGSHARE") begin:Predictor
@ -98,7 +100,7 @@ module bpred
.Prediction(BPPredF),
// update
.UpdatePC(PCE),
.UpdateEN(InstrClassE[0]),
.UpdateEN(InstrClassE[0] & ~StallE),
.PCSrcE(PCSrcE),
.UpdatePrediction(UpdateBPPredE));
end
@ -119,16 +121,19 @@ module bpred
// Part 2 Branch target address prediction
// *** For now the BTB will house the direct and indirect targets
// *** getting to many false positivies from the BTB, we need a partial TAG to reduce this.
BTBPredictor TargetPredictor(.clk(clk),
.reset(reset),
.*, // Stalls and flushes
.LookUpPC(PCNextF),
.TargetPC(BTBPredPCF),
.InstrClass(BPInstrClassF),
.Valid(BTBValidF),
// update
.UpdateEN(InstrClassE[2] | InstrClassE[1] | InstrClassE[0]),
.UpdateEN((|InstrClassE | (PredictionInstrClassWrongE)) & ~StallE),
.UpdatePC(PCE),
.UpdateTarget(PCTargetE),
.UpdateInvalid(PredictionInstrClassWrongE),
.UpdateInstrClass(InstrClassE));
// need to forward when updating to the same address as reading.
@ -139,9 +144,9 @@ module bpred
// *** need to add the logic to restore RAS on flushes. We will use incr for this.
RASPredictor RASPredictor(.clk(clk),
.reset(reset),
.pop(BPInstrClassF[3]),
.pop(BPInstrClassF[3] & ~StallF),
.popPC(RASPCF),
.push(InstrClassE[3]),
.push(InstrClassE[4] & ~StallE),
.incr(1'b0),
.pushPC(PCLinkE));
@ -188,7 +193,8 @@ module bpred
assign FallThroughWrongE = PCLinkE != PCD;
assign PredictionDirWrongE = (BPPredE[1] ^ PCSrcE) & InstrClassE[0];
assign PredictionPCWrongE = PCSrcE ? TargetWrongE : FallThroughWrongE;
assign BPPredWrongE = (PredictionPCWrongE | PredictionDirWrongE) & (|InstrClassE);
assign PredictionInstrClassWrongE = InstrClassE != BPInstrClassE;
assign BPPredWrongE = ((PredictionPCWrongE | PredictionDirWrongE) & (|InstrClassE)) | PredictionInstrClassWrongE;
// Update predictors

View File

@ -42,22 +42,24 @@ module gsharePredictor
);
logic [k-1:0] GHRF, GHRD, GHRE;
logic [k-1:0] LookUpPCIndexD, LookUpPCIndexE;
logic [k-1:0] GHRF, GHRD, GHRE, GHRENext;
//logic [k-1:0] LookUpPCIndexD, LookUpPCIndexE;
logic [k-1:0] LookUpPCIndex, UpdatePCIndex;
logic [1:0] PredictionMemory;
logic DoForwarding, DoForwardingF;
logic [1:0] UpdatePredictionF;
assign GHRENext = {PCSrcE, GHRE[k-1:1]};
flopenr #(k) GlobalHistoryRegister(.clk(clk),
.reset(reset),
.en(UpdateEN),
.d({PCSrcE, GHRF[k-1:1] }),
.d(GHRENext),
.q(GHRF));
// for gshare xor the PC with the GHR
assign UpdatePCIndex = GHRE ^ UpdatePC[k:1];
assign UpdatePCIndex = GHRENext ^ UpdatePC[k:1];
assign LookUpPCIndex = GHRF ^ LookUpPC[k:1];
// Make Prediction by reading the correct address in the PHT and also update the new address in the PHT
// GHR referes to the address that the past k branches points to in the prediction stage
@ -66,7 +68,7 @@ module gsharePredictor
.reset(reset),
.RA1(LookUpPCIndex),
.RD1(PredictionMemory),
.REN1(1'b1),
.REN1(~StallF),
.WA1(UpdatePCIndex),
.WD1(UpdatePrediction),
.WEN1(UpdateEN),
@ -92,6 +94,7 @@ module gsharePredictor
assign Prediction = DoForwardingF ? UpdatePredictionF : PredictionMemory;
//pipeline for GHR
/* -----\/----- EXCLUDED -----\/-----
flopenrc #(k) LookUpDReg(.clk(clk),
.reset(reset),
.en(~StallD),
@ -105,5 +108,21 @@ module gsharePredictor
.clear(FlushE),
.d(LookUpPCIndexD),
.q(LookUpPCIndexE));
-----/\----- EXCLUDED -----/\----- */
flopenrc #(k) GHRRegD(.clk(clk),
.reset(reset),
.en(~StallD),
.clear(FlushD),
.d(GHRF),
.q(GHRD));
flopenrc #(k) GHRRegE(.clk(clk),
.reset(reset),
.en(~StallE),
.clear(FlushE),
.d(GHRD),
.q(GHRE));
endmodule

View File

@ -85,7 +85,7 @@ module ifu (
// branch predictor signals
logic SelBPPredF;
logic [`XLEN-1:0] BPPredPCF, PCCorrectE, PCNext0F, PCNext1F;
logic [3:0] InstrClassD, InstrClassE;
logic [4:0] InstrClassD, InstrClassE;
// *** put memory interface on here, InstrF becomes output
@ -131,7 +131,7 @@ module ifu (
.reset(reset),
.StallF(StallF),
.StallD(StallD),
.StallE(1'b0), // *** may need this eventually
.StallE(StallE),
.FlushF(FlushF),
.FlushD(FlushD),
.FlushE(FlushE),
@ -169,8 +169,9 @@ module ifu (
// the branch predictor needs a compact decoding of the instruction class.
// *** consider adding in the alternate return address x5 for returns.
assign InstrClassD[3] = InstrD[6:0] == 7'h67 && InstrD[19:15] == 5'h01; // return
assign InstrClassD[2] = InstrD[6:0] == 7'h67 && InstrD[19:15] != 5'h01; // jump register, but not return
assign InstrClassD[4] = (InstrD[6:0] & 7'h77) == 7'h67 && (InstrD[11:07] & 5'h1B) == 5'h01; // jal(r) must link to ra or r5
assign InstrClassD[3] = InstrD[6:0] == 7'h67 && (InstrD[19:15] & 5'h1B) == 5'h01; // return must link to ra or r5
assign InstrClassD[2] = InstrD[6:0] == 7'h67 && (InstrD[19:15] & 5'h1B) != 5'h01; // jump register, but not return
assign InstrClassD[1] = InstrD[6:0] == 7'h6F; // jump
assign InstrClassD[0] = InstrD[6:0] == 7'h63; // branch
@ -197,14 +198,14 @@ module ifu (
flopenr #(`XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM);
// flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); // *** probably not needed; delete later
flopenrc #(4) InstrClassRegE(.clk(clk),
flopenrc #(5) InstrClassRegE(.clk(clk),
.reset(reset),
.en(~StallE),
.clear(FlushE),
.d(InstrClassD),
.q(InstrClassE));
flopenrc #(4) InstrClassRegM(.clk(clk),
flopenrc #(5) InstrClassRegM(.clk(clk),
.reset(reset),
.en(~StallM),
.clear(FlushM),

View File

@ -28,7 +28,7 @@
module csr (
input logic clk, reset,
input logic FlushW, StallW,
input logic FlushW, StallD, StallE, StallM, StallW,
input logic [31:0] InstrM,
input logic [`XLEN-1:0] PCM, SrcAM,
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM,

View File

@ -29,8 +29,9 @@
module csrc (
input logic clk, reset,
input logic StallD, StallE, StallM, StallW,
input logic InstrValidW, LoadStallD, CSRMWriteM, BPPredWrongM,
input logic [3:0] InstrClassM,
input logic [3:0] InstrClassM,
input logic [11:0] CSRAdrM,
input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] CSRWriteValM,
@ -61,10 +62,10 @@ module csrc (
logic [`COUNTERS:0] MCOUNTEN;
assign MCOUNTEN[0] = 1'b1;
assign MCOUNTEN[1] = 1'b0;
assign MCOUNTEN[2] = InstrValidW;
assign MCOUNTEN[3] = LoadStallD;
assign MCOUNTEN[4] = BPPredWrongM;
assign MCOUNTEN[5] = InstrClassM[0];
assign MCOUNTEN[2] = InstrValidW & ~StallW;
assign MCOUNTEN[3] = LoadStallD & ~StallD;
assign MCOUNTEN[4] = BPPredWrongM & ~StallM;
assign MCOUNTEN[5] = InstrClassM[0] & ~StallM;
assign MCOUNTEN[`COUNTERS:6] = 0;
genvar j;
@ -91,7 +92,7 @@ module csrc (
// Write / update counters
// Only the Machine mode versions of the counter CSRs are writable
if (`XLEN==64) begin // 64-bit counters
flopr #(64) HPMCOUNTERreg_j(clk, reset, NextHPMCOUNTERM[j], HPMCOUNTER_REGW[j]);
flopenr #(64) HPMCOUNTERreg_j(clk, reset, ~StallW, NextHPMCOUNTERM[j], HPMCOUNTER_REGW[j]);
end
else begin // 32-bit low and high counters
logic [`COUNTERS:0] WriteHPMCOUNTERHM;
@ -102,8 +103,8 @@ module csrc (
assign NextHPMCOUNTERHM[j] = WriteHPMCOUNTERHM[j] ? CSRWriteValM : HPMCOUNTERPlusM[j][63:32];
// Counter CSRs
flopr #(32) HPMCOUNTERreg_j(clk, reset, NextHPMCOUNTERM[j], HPMCOUNTER_REGW[j][31:0]);
flopr #(32) HPMCOUNTERHreg_j(clk, reset, NextHPMCOUNTERHM[j], HPMCOUNTER_REGW[j][63:32]);
flopenr #(32) HPMCOUNTERreg_j(clk, reset, ~StallW, NextHPMCOUNTERM[j], HPMCOUNTER_REGW[j][31:0]);
flopenr #(32) HPMCOUNTERHreg_j(clk, reset, ~StallW, NextHPMCOUNTERHM[j], HPMCOUNTER_REGW[j][63:32]);
end
end // end for

View File

@ -33,6 +33,7 @@ module csri #(parameter
SIE = 12'h104,
SIP = 12'h144) (
input logic clk, reset,
input logic StallW,
input logic CSRMWriteM, CSRSWriteM,
input logic [11:0] CSRAdrM,
input logic ExtIntM, TimerIntM, SwIntM,
@ -59,10 +60,10 @@ module csri #(parameter
end
// Interrupt Write Enables
assign WriteMIPM = CSRMWriteM && (CSRAdrM == MIP);
assign WriteMIEM = CSRMWriteM && (CSRAdrM == MIE);
assign WriteSIPM = CSRSWriteM && (CSRAdrM == SIP);
assign WriteSIEM = CSRSWriteM && (CSRAdrM == SIE);
assign WriteMIPM = CSRMWriteM && (CSRAdrM == MIP) && ~StallW;
assign WriteMIEM = CSRMWriteM && (CSRAdrM == MIE) && ~StallW;
assign WriteSIPM = CSRSWriteM && (CSRAdrM == SIP) && ~StallW;
assign WriteSIEM = CSRSWriteM && (CSRAdrM == SIE) && ~StallW;
// Interrupt Pending and Enable Registers
// MEIP, MTIP, MSIP are read-only

View File

@ -75,6 +75,7 @@ module csrm #(parameter
DSCRATCH0 = 12'h7B2,
DSCRATCH1 = 12'h7B3) (
input logic clk, reset,
input logic StallW,
input logic CSRMWriteM, MTrapM,
input logic [11:0] CSRAdrM,
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, MSTATUS_REGW,
@ -107,34 +108,34 @@ module csrm #(parameter
assign MISA_REGW = {(`XLEN == 32 ? 2'b01 : 2'b10), {(`XLEN-28){1'b0}}, MISAbits};
// Write machine Mode CSRs
assign WriteMSTATUSM = CSRMWriteM && (CSRAdrM == MSTATUS);
assign WriteMTVECM = CSRMWriteM && (CSRAdrM == MTVEC);
assign WriteMEDELEGM = CSRMWriteM && (CSRAdrM == MEDELEG);
assign WriteMIDELEGM = CSRMWriteM && (CSRAdrM == MIDELEG);
assign WriteMSCRATCHM = CSRMWriteM && (CSRAdrM == MSCRATCH);
assign WriteMEPCM = MTrapM | (CSRMWriteM && (CSRAdrM == MEPC));
assign WriteMCAUSEM = MTrapM | (CSRMWriteM && (CSRAdrM == MCAUSE));
assign WriteMTVALM = MTrapM | (CSRMWriteM && (CSRAdrM == MTVAL));
assign WritePMPCFG0M = (CSRMWriteM && (CSRAdrM == PMPCFG0));
assign WritePMPCFG2M = (CSRMWriteM && (CSRAdrM == PMPCFG2));
assign WritePMPADDRM[0] = (CSRMWriteM && (CSRAdrM == PMPADDR0));
assign WritePMPADDRM[1] = (CSRMWriteM && (CSRAdrM == PMPADDR1));
assign WritePMPADDRM[2] = (CSRMWriteM && (CSRAdrM == PMPADDR2));
assign WritePMPADDRM[3] = (CSRMWriteM && (CSRAdrM == PMPADDR3));
assign WritePMPADDRM[4] = (CSRMWriteM && (CSRAdrM == PMPADDR4));
assign WritePMPADDRM[5] = (CSRMWriteM && (CSRAdrM == PMPADDR5));
assign WritePMPADDRM[6] = (CSRMWriteM && (CSRAdrM == PMPADDR6));
assign WritePMPADDRM[7] = (CSRMWriteM && (CSRAdrM == PMPADDR7));
assign WritePMPADDRM[8] = (CSRMWriteM && (CSRAdrM == PMPADDR8));
assign WritePMPADDRM[9] = (CSRMWriteM && (CSRAdrM == PMPADDR9));
assign WritePMPADDRM[10] = (CSRMWriteM && (CSRAdrM == PMPADDR10));
assign WritePMPADDRM[11] = (CSRMWriteM && (CSRAdrM == PMPADDR11));
assign WritePMPADDRM[12] = (CSRMWriteM && (CSRAdrM == PMPADDR12));
assign WritePMPADDRM[13] = (CSRMWriteM && (CSRAdrM == PMPADDR13));
assign WritePMPADDRM[14] = (CSRMWriteM && (CSRAdrM == PMPADDR14));
assign WritePMPADDRM[15] = (CSRMWriteM && (CSRAdrM == PMPADDR15));
assign WriteMCOUNTERENM = CSRMWriteM && (CSRAdrM == MCOUNTEREN);
assign WriteMCOUNTINHIBITM = CSRMWriteM && (CSRAdrM == MCOUNTINHIBIT);
assign WriteMSTATUSM = CSRMWriteM && (CSRAdrM == MSTATUS) && ~StallW;
assign WriteMTVECM = CSRMWriteM && (CSRAdrM == MTVEC) && ~StallW;
assign WriteMEDELEGM = CSRMWriteM && (CSRAdrM == MEDELEG) && ~StallW;
assign WriteMIDELEGM = CSRMWriteM && (CSRAdrM == MIDELEG) && ~StallW;
assign WriteMSCRATCHM = CSRMWriteM && (CSRAdrM == MSCRATCH) && ~StallW;
assign WriteMEPCM = MTrapM | (CSRMWriteM && (CSRAdrM == MEPC)) && ~StallW;
assign WriteMCAUSEM = MTrapM | (CSRMWriteM && (CSRAdrM == MCAUSE)) && ~StallW;
assign WriteMTVALM = MTrapM | (CSRMWriteM && (CSRAdrM == MTVAL)) && ~StallW;
assign WritePMPCFG0M = (CSRMWriteM && (CSRAdrM == PMPCFG0)) && ~StallW;
assign WritePMPCFG2M = (CSRMWriteM && (CSRAdrM == PMPCFG2)) && ~StallW;
assign WritePMPADDRM[0] = (CSRMWriteM && (CSRAdrM == PMPADDR0)) && ~StallW;
assign WritePMPADDRM[1] = (CSRMWriteM && (CSRAdrM == PMPADDR1)) && ~StallW;
assign WritePMPADDRM[2] = (CSRMWriteM && (CSRAdrM == PMPADDR2)) && ~StallW;
assign WritePMPADDRM[3] = (CSRMWriteM && (CSRAdrM == PMPADDR3)) && ~StallW;
assign WritePMPADDRM[4] = (CSRMWriteM && (CSRAdrM == PMPADDR4)) && ~StallW;
assign WritePMPADDRM[5] = (CSRMWriteM && (CSRAdrM == PMPADDR5)) && ~StallW;
assign WritePMPADDRM[6] = (CSRMWriteM && (CSRAdrM == PMPADDR6)) && ~StallW;
assign WritePMPADDRM[7] = (CSRMWriteM && (CSRAdrM == PMPADDR7)) && ~StallW;
assign WritePMPADDRM[8] = (CSRMWriteM && (CSRAdrM == PMPADDR8)) && ~StallW;
assign WritePMPADDRM[9] = (CSRMWriteM && (CSRAdrM == PMPADDR9)) && ~StallW;
assign WritePMPADDRM[10] = (CSRMWriteM && (CSRAdrM == PMPADDR10)) && ~StallW;
assign WritePMPADDRM[11] = (CSRMWriteM && (CSRAdrM == PMPADDR11)) && ~StallW;
assign WritePMPADDRM[12] = (CSRMWriteM && (CSRAdrM == PMPADDR12)) && ~StallW;
assign WritePMPADDRM[13] = (CSRMWriteM && (CSRAdrM == PMPADDR13)) && ~StallW;
assign WritePMPADDRM[14] = (CSRMWriteM && (CSRAdrM == PMPADDR14)) && ~StallW;
assign WritePMPADDRM[15] = (CSRMWriteM && (CSRAdrM == PMPADDR15)) && ~StallW;
assign WriteMCOUNTERENM = CSRMWriteM && (CSRAdrM == MCOUNTEREN) && ~StallW;
assign WriteMCOUNTINHIBITM = CSRMWriteM && (CSRAdrM == MCOUNTINHIBIT) && ~StallW;
// CSRs
flopenl #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, CSRWriteValM, `XLEN'b0, MTVEC_REGW); //busybear: changed reset value to 0

View File

@ -36,6 +36,7 @@ module csrn #(parameter
UTVAL = 12'h043,
UIP = 12'h044) (
input logic clk, reset,
input logic StallW,
input logic CSRNWriteM, UTrapM,
input logic [11:0] CSRAdrM,
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, USTATUS_REGW,
@ -56,11 +57,11 @@ module csrn #(parameter
logic [`XLEN-1:0] USCRATCH_REGW, UCAUSE_REGW, UTVAL_REGW;
// Write enables
assign WriteUSTATUSM = CSRNWriteM && (CSRAdrM == USTATUS);
assign WriteUTVECM = CSRNWriteM && (CSRAdrM == UTVEC);
assign WriteUEPCM = UTrapM | (CSRNWriteM && (CSRAdrM == UEPC));
assign WriteUCAUSEM = UTrapM | (CSRNWriteM && (CSRAdrM == UCAUSE));
assign WriteUTVALM = UTrapM | (CSRNWriteM && (CSRAdrM == UTVAL));
assign WriteUSTATUSM = CSRNWriteM && (CSRAdrM == USTATUS) && ~StallW;
assign WriteUTVECM = CSRNWriteM && (CSRAdrM == UTVEC) && ~StallW;
assign WriteUEPCM = UTrapM | (CSRNWriteM && (CSRAdrM == UEPC)) && ~StallW;
assign WriteUCAUSEM = UTrapM | (CSRNWriteM && (CSRAdrM == UCAUSE)) && ~StallW;
assign WriteUTVALM = UTrapM | (CSRNWriteM && (CSRAdrM == UTVAL)) && ~StallW;
// CSRs
flopenl #(`XLEN) UTVECreg(clk, reset, WriteUTVECM, CSRWriteValM, `RESET_VECTOR, UTVEC_REGW);
@ -95,4 +96,4 @@ module csrn #(parameter
assign IllegalCSRNAccessM = 1;
end
endgenerate
endmodule
endmodule

View File

@ -41,6 +41,7 @@ module csrs #(parameter
SIP= 12'h144,
SATP = 12'h180) (
input logic clk, reset,
input logic StallW,
input logic CSRSWriteM, STrapM,
input logic [11:0] CSRAdrM,
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
@ -66,14 +67,14 @@ module csrs #(parameter
logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM;
logic [`XLEN-1:0] SSCRATCH_REGW, SCAUSE_REGW, STVAL_REGW;
assign WriteSSTATUSM = CSRSWriteM && (CSRAdrM == SSTATUS);
assign WriteSTVECM = CSRSWriteM && (CSRAdrM == STVEC);
assign WriteSSCRATCHM = CSRSWriteM && (CSRAdrM == SSCRATCH);
assign WriteSEPCM = STrapM | (CSRSWriteM && (CSRAdrM == SEPC));
assign WriteSCAUSEM = STrapM | (CSRSWriteM && (CSRAdrM == SCAUSE));
assign WriteSTVALM = STrapM | (CSRSWriteM && (CSRAdrM == STVAL));
assign WriteSATPM = STrapM | (CSRSWriteM && (CSRAdrM == SATP));
assign WriteSCOUNTERENM = CSRSWriteM && (CSRAdrM == SCOUNTEREN);
assign WriteSSTATUSM = CSRSWriteM && (CSRAdrM == SSTATUS) && ~StallW;
assign WriteSTVECM = CSRSWriteM && (CSRAdrM == STVEC) && ~StallW;
assign WriteSSCRATCHM = CSRSWriteM && (CSRAdrM == SSCRATCH) && ~StallW;
assign WriteSEPCM = STrapM | (CSRSWriteM && (CSRAdrM == SEPC)) && ~StallW;
assign WriteSCAUSEM = STrapM | (CSRSWriteM && (CSRAdrM == SCAUSE)) && ~StallW;
assign WriteSTVALM = STrapM | (CSRSWriteM && (CSRAdrM == STVAL)) && ~StallW;
assign WriteSATPM = STrapM | (CSRSWriteM && (CSRAdrM == SATP)) && ~StallW;
assign WriteSCOUNTERENM = CSRSWriteM && (CSRAdrM == SCOUNTEREN) && ~StallW;
// CSRs
flopenl #(`XLEN) STVECreg(clk, reset, WriteSTVECM, CSRWriteValM, zero, STVEC_REGW); //busybear: change reset to 0

View File

@ -32,6 +32,7 @@ module csru #(parameter
FRM = 12'h002,
FCSR = 12'h003) (
input logic clk, reset,
input logic StallW,
input logic CSRUWriteM,
input logic [11:0] CSRAdrM,
input logic [`XLEN-1:0] CSRWriteValM,
@ -50,9 +51,9 @@ module csru #(parameter
logic [4:0] NextFFLAGSM;
// Write enables
assign WriteFCSRM = CSRUWriteM && (CSRAdrM == FCSR);
assign WriteFFLAGSM = CSRUWriteM && (CSRAdrM == FFLAGS) | WriteFCSRM ;
assign WriteFRMM = CSRUWriteM && (CSRAdrM == FRM) | WriteFCSRM;
assign WriteFCSRM = CSRUWriteM && (CSRAdrM == FCSR) && ~StallW;
assign WriteFFLAGSM = (CSRUWriteM && (CSRAdrM == FFLAGS) | WriteFCSRM) && ~StallW;
assign WriteFRMM = (CSRUWriteM && (CSRAdrM == FRM) | WriteFCSRM) && ~StallW;
// Write Values
assign NextFRMM = WriteFCSRM ? CSRWriteValM[7:5] : CSRWriteValM[2:0];
@ -81,4 +82,4 @@ module csru #(parameter
assign IllegalCSRUAccessM = 1;
end
endgenerate
endmodule
endmodule

View File

@ -49,7 +49,7 @@ module privileged (
output logic [1:0] PrivilegeModeW,
output logic [`XLEN-1:0] SATP_REGW,
output logic [2:0] FRM_REGW,
input logic FlushD, FlushE, FlushM, StallD, StallW, StallE, StallM
input logic FlushD, FlushE, FlushM, StallD, StallE, StallM, StallW
);
logic [1:0] NextPrivilegeModeM;

View File

@ -27,9 +27,10 @@
`include "wally-config.vh"
module function_radix(reset, ProgramAddrMapFile, ProgramLabelMapFile);
module FunctionName(reset, clk, ProgramAddrMapFile, ProgramLabelMapFile);
input logic reset;
input logic clk;
input string ProgramAddrMapFile;
input string ProgramLabelMapFile;
@ -38,13 +39,23 @@ module function_radix(reset, ProgramAddrMapFile, ProgramLabelMapFile);
string FunctionName;
logic [`XLEN-1:0] pc, FunctionAddr;
logic [`XLEN-1:0] PCF, PCD, PCE, FunctionAddr;
logic StallD, StallE, FlushD, FlushE;
integer ProgramAddrIndex;
// *** I should look into the system verilog objects instead of signal spy.
initial begin
$init_signal_spy("/testbench/dut/hart/PCE", "/testbench/functionRadix/function_radix/pc");
end
assign PCF = testbench.dut.hart.PCF;
assign StallD = testbench.dut.hart.StallD;
assign StallE = testbench.dut.hart.StallE;
assign FlushD = testbench.dut.hart.FlushD;
assign FlushE = testbench.dut.hart.FlushE;
// copy from ifu
// when the F and D stages are flushed we need to ensure the PCE is held so that the function name does not
// erroneously change.
flopenrc #(`XLEN) PCDReg(clk, reset, 1'b0, ~StallD, FlushE & FlushD ? PCE : PCF, PCD);
flopenr #(`XLEN) PCEReg(clk, reset, ~StallE, FlushE ? PCE : PCD, PCE);
task automatic bin_search_min;
input logic [`XLEN-1:0] pc;
@ -74,7 +85,7 @@ module function_radix(reset, ProgramAddrMapFile, ProgramLabelMapFile);
end else if( array[mid] > pc) begin
right = mid -1;
end else begin
$display("Critical Error in function radix. PC, %x not found.", pc);
$display("Critical Error in FunctionName. PC, %x not found.", pc);
return;
//$stop();
end
@ -141,8 +152,8 @@ module function_radix(reset, ProgramAddrMapFile, ProgramLabelMapFile);
end
always @(pc) begin
bin_search_min(pc, ProgramAddrMapLineCount, ProgramAddrMapMemory, FunctionAddr, ProgramAddrIndex);
always @(PCE) begin
bin_search_min(PCE, ProgramAddrMapLineCount, ProgramAddrMapMemory, FunctionAddr, ProgramAddrIndex);
end

View File

@ -39,7 +39,7 @@ module testbench_busybear();
// read pc trace file
integer data_file_PC, scan_file_PC;
initial begin
data_file_PC = $fopen("/courses/e190ax/busybear_boot/parsedPC.txt", "r");
data_file_PC = $fopen("../../../busybear_boot/parsedPC.txt", "r");
if (data_file_PC == 0) begin
$display("file couldn't be opened");
$stop;
@ -48,7 +48,7 @@ module testbench_busybear();
integer data_file_PCW, scan_file_PCW;
initial begin
data_file_PCW = $fopen("/courses/e190ax/busybear_boot/parsedPC.txt", "r");
data_file_PCW = $fopen("../../../busybear_boot/parsedPC.txt", "r");
if (data_file_PCW == 0) begin
$display("file couldn't be opened");
$stop;
@ -58,7 +58,7 @@ module testbench_busybear();
// read register trace file
integer data_file_rf, scan_file_rf;
initial begin
data_file_rf = $fopen("/courses/e190ax/busybear_boot/parsedRegs.txt", "r");
data_file_rf = $fopen("../../../busybear_boot/parsedRegs.txt", "r");
if (data_file_rf == 0) begin
$display("file couldn't be opened");
$stop;
@ -68,7 +68,7 @@ module testbench_busybear();
// read CSR trace file
integer data_file_csr, scan_file_csr;
initial begin
data_file_csr = $fopen("/courses/e190ax/busybear_boot/parsedCSRs.txt", "r");
data_file_csr = $fopen("../../../busybear_boot/parsedCSRs.txt", "r");
if (data_file_csr == 0) begin
$display("file couldn't be opened");
$stop;
@ -78,7 +78,7 @@ module testbench_busybear();
// read memreads trace file
integer data_file_memR, scan_file_memR;
initial begin
data_file_memR = $fopen("/courses/e190ax/busybear_boot/parsedMemRead.txt", "r");
data_file_memR = $fopen("../../../busybear_boot/parsedMemRead.txt", "r");
if (data_file_memR == 0) begin
$display("file couldn't be opened");
$stop;
@ -88,7 +88,7 @@ module testbench_busybear();
// read memwrite trace file
integer data_file_memW, scan_file_memW;
initial begin
data_file_memW = $fopen("/courses/e190ax/busybear_boot/parsedMemWrite.txt", "r");
data_file_memW = $fopen("../../../busybear_boot/parsedMemWrite.txt", "r");
if (data_file_memW == 0) begin
$display("file couldn't be opened");
$stop;
@ -97,10 +97,10 @@ module testbench_busybear();
// initial loading of memories
initial begin
$readmemh("/courses/e190ax/busybear_boot/bootmem.txt", dut.uncore.bootdtim.RAM, 'h1000 >> 3);
$readmemh("/courses/e190ax/busybear_boot/ram.txt", dut.uncore.dtim.RAM);
$readmemh("/courses/e190ax/busybear_boot/bootmem.txt", dut.imem.bootram, 'h1000 >> 3);
$readmemh("/courses/e190ax/busybear_boot/ram.txt", dut.imem.RAM);
$readmemh("../../../busybear_boot/bootmem.txt", dut.uncore.bootdtim.RAM, 'h1000 >> 3);
$readmemh("../../../busybear_boot/ram.txt", dut.uncore.dtim.RAM);
$readmemh("../../../busybear_boot/bootmem.txt", dut.imem.bootram, 'h1000 >> 3);
$readmemh("../../../busybear_boot/ram.txt", dut.imem.RAM);
$readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.Predictor.DirPredictor.PHT.memory);
$readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.TargetPredictor.memory.memory);
end

View File

@ -28,7 +28,6 @@
module testbench();
parameter DEBUG = 0;
parameter TESTSBP = 0;
logic clk;
logic reset;
@ -321,7 +320,8 @@ string tests32i[] = {
};
string testsBP64[] = '{
"rv64BP/reg-test", "10000"
"rv64BP/simple", "10000",
"rv64BP/sieve", "1000000"
};
string tests[];
string ProgramAddrMapFile, ProgramLabelMapFile;
@ -343,8 +343,8 @@ string tests32i[] = {
// pick tests based on modes supported
initial
if (`XLEN == 64) begin // RV64
if (TESTSBP) begin
tests = testsBP64;
if(`TESTSBP) begin
tests = testsBP64;
end else begin
tests = {tests64i};
if (`C_SUPPORTED) tests = {tests, tests64ic};
@ -485,10 +485,11 @@ string tests32i[] = {
end // always @ (negedge clk)
// track the current function or global label
if (DEBUG == 1) begin : functionRadix
function_radix function_radix(.reset(reset),
.ProgramAddrMapFile(ProgramAddrMapFile),
.ProgramLabelMapFile(ProgramLabelMapFile));
if (DEBUG == 1) begin : FunctionName
FunctionName FunctionName(.reset(reset),
.clk(clk),
.ProgramAddrMapFile(ProgramAddrMapFile),
.ProgramLabelMapFile(ProgramLabelMapFile));
end
// initialize the branch predictor