mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
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:
parent
6e83ccc3c4
commit
a64a37d702
5
.gitignore
vendored
5
.gitignore
vendored
@ -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
23
testsBP/crt0/Makefile
Normal 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
213
testsBP/crt0/isr.s
Normal 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
60
testsBP/crt0/start.s
Normal 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
244
testsBP/linker.x
Normal 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
92
testsBP/makefile.inc
Normal 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
15
testsBP/sieve/Makefile
Normal 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
101
testsBP/sieve/sieve.c
Normal 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
15
testsBP/simple/Makefile
Normal 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
11
testsBP/simple/fail.s
Normal 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
6
testsBP/simple/header.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __header
|
||||
#define __header
|
||||
|
||||
int fail();
|
||||
int simple_csrbr_test();
|
||||
#endif
|
10
testsBP/simple/main.c
Normal file
10
testsBP/simple/main.c
Normal 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
61
testsBP/simple/sample.s
Normal 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
|
@ -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) }
|
||||
}
|
||||
|
145
wally-pipelined/bin/exe2memfile0.pl
Executable file
145
wally-pipelined/bin/exe2memfile0.pl
Executable 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);
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
1024
wally-pipelined/config/rv64BP/BTBPredictor.txt
Normal file
1024
wally-pipelined/config/rv64BP/BTBPredictor.txt
Normal file
File diff suppressed because it is too large
Load Diff
1024
wally-pipelined/config/rv64BP/twoBitPredictor.txt
Normal file
1024
wally-pipelined/config/rv64BP/twoBitPredictor.txt
Normal file
File diff suppressed because it is too large
Load Diff
101
wally-pipelined/config/rv64BP/wally-config.vh
Normal file
101
wally-pipelined/config/rv64BP/wally-config.vh
Normal 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
|
31
wally-pipelined/config/rv64BP/wally-constants.vh
Normal file
31
wally-pipelined/config/rv64BP/wally-constants.vh
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user