9 Commits

Author SHA1 Message Date
0f4e3f7c72 saving current changes 2026-05-01 15:47:18 +01:00
0a76c24490 saving current changes 2026-04-19 23:07:57 +01:00
e493518509 ported over working martrix multiplication 2026-04-17 23:18:25 +01:00
c692932124 saving current changes 2026-04-10 03:41:30 +01:00
dc9c8578b6 other benchmarks 2026-04-10 02:50:17 +01:00
913d17224b stable malloc 2026-04-10 00:01:22 +01:00
2d212949d9 added l1 tlb counters 2026-04-09 14:04:02 +01:00
26b025b556 enabled performance counters 2026-04-09 13:17:48 +01:00
056d4e0821 manual performance enable for dtlb 2026-04-09 12:50:48 +01:00
52 changed files with 61106 additions and 3702 deletions

View File

@@ -0,0 +1,16 @@
scp ../../start.S home-1:/home/akilan/cheri/output/sdk/bin/
# scp main.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../malloc.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../malloc_test.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../link.ld home-1:/home/akilan/cheri/output/sdk/bin/
scp matrixmul.c home-1:/home/akilan/cheri/output/sdk/bin/
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -Wl,-Ttext=0x80000000 -o testC start.S malloc.c memaccess.c'
ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -DDEFINE_MALLOC -DDEFINE_FREE -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -T link.ld -o testC start.S matrixmul.c malloc.c malloc_test.c'
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./llvm-objdump -d testC'
scp home-1:/home/akilan/cheri/output/sdk/bin/testC ../../../

View File

@@ -0,0 +1,217 @@
// Source: https://github.com/ivanbgd/Matrix-Multiplication-MatMul-C/blob/master/matmul_1d_seq.c
#define MATMUL_1D
#ifdef MATMUL_1D
/* Matrices are represented as 1-D arrays in memory.
* That means they are contiguous in memory.
* Minimum dimension is 1, not 0, and internal dimensions must match. */
// #include <math.h>
// #include <omp.h>
// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>
// #include <time.h>
#include <cheriintrin.h>
#include <stddef.h>
#include <stdint.h>
void free(void * __capability ptr);
void * __capability malloc(size_t size);
/* Initializes vector or matrix, sequentially, with indices. */
void init_seq(int * __capability a, const unsigned n_rows_a, const unsigned n_cols_a) {
for (size_t i = 0; i < n_rows_a; i++) {
for (size_t j = 0; j < n_cols_a; j++) {
a[i*n_cols_a + j] = 2;
}
}
}
// static unsigned int seed = 123456789; // must be initialized somehow
// unsigned int rand_test(void)
// {
// seed = (1103515245 * seed + 12345);
// return (seed >> 16) & 0x7FFF; // 15-bit result
// }
// /* Initializes vector or matrix, randomly. */
// void init_rand(double *a, const unsigned n_rows_a, const unsigned n_cols_a) {
// for (size_t i = 0; i < n_rows_a; i++) {
// for (size_t j = 0; j < n_cols_a; j++) {
// a[i*n_cols_a + j] = rand_test() / 32767.0;
// // rand_test() / (double)RAND_MAX;
// }
// }
// }
/* Takes and returns a new matrix, t, which is a transpose of the original one, m.
It's also flat in memory, i.e., 1-D, but it should be looked at as a transpose
of m, meaning, n_rows_t == n_cols_m, and n_cols_t == n_rows_m.
The original matrix m stays intact. */
int __capability * transpose(const int __capability *m, const unsigned n_rows_m, const unsigned n_cols_m, int __capability *t) {
for (size_t i = 0; i < n_rows_m; i++) {
for (size_t j = 0; j < n_cols_m; j++) {
t[j*n_rows_m + i] = m[i*n_cols_m + j];
}
}
return t;
}
/* Dot product of two arrays, or matrix product
* Allocates and returns an array.
* This variant doesn't transpose matrix b, and it's a lot slower. */
int * __capability dot_simple(const int * __capability a, const unsigned n_rows_a, const unsigned n_cols_a,\
const int * __capability b, const unsigned n_rows_b, const unsigned n_cols_b) {
if (n_cols_a != n_rows_b) {
// printf("#columns A must be equal to #rows B!\n");
// system("pause");
// exit(-2);
while(1);
}
int * __capability c = malloc(n_rows_a * n_cols_b * sizeof(*c));
if (c == NULL) {
// printf("Couldn't allocate memory!\n");
// system("pause");
// exit(-1);
while(1);
}
for (size_t i = 0; i < n_rows_a; i++) {
for (size_t k = 0; k < n_cols_b; k++) {
int sum = 0;
for (size_t j = 0; j < n_cols_a; j++) {
sum += a[i*n_cols_a + j] * b[j*n_cols_b + k];
}
c[i*n_cols_b + k] = sum;
}
}
return c;
}
/* Dot product of two arrays, or matrix product
* Allocates and returns an array.
* This variant transposes matrix b, and it's a lot faster. */
int * __capability dot(const int * __capability a, const unsigned n_rows_a, const unsigned n_cols_a, \
const int * __capability b, const unsigned n_rows_b, const unsigned n_cols_b) {
if (n_cols_a != n_rows_b) {
// printf("#columns A must be equal to #rows B!\n");
// system("pause");
// exit(-2);
}
int * __capability bt = malloc(n_rows_b * n_cols_b * sizeof(*b));
int * __capability c = malloc(n_rows_a * n_cols_b * sizeof(*c));
if ((c == NULL) || (bt == NULL)) {
// printf("Couldn't allocate memory!\n");
// system("pause");
// exit(-1);
}
bt = transpose(b, n_rows_b, n_cols_b, bt);
for (size_t i = 0; i < n_rows_a; i++) {
for (size_t k = 0; k < n_cols_b; k++) {
int sum = 0;
for (size_t j = 0; j < n_cols_a; j++) {
sum += a[i*n_cols_a + j] * bt[k*n_rows_b + j];
}
c[i*n_cols_b + k] = sum;
}
}
free(bt);
return c;
}
/* Prints vector, or matrix. */
// void print(const double *a, const unsigned n_rows_a, const unsigned n_cols_a) {
// for (size_t i = 0; i < n_rows_a; i++) {
// for (size_t j = 0; j < n_cols_a; j++) {
// printf("%8.3f ", a[i*n_cols_a + j]);
// }
// printf("\n");
// }
// printf("\n");
// }
int main(void) {
/* Intializes random number generator */
// time_t t;
// srand((unsigned)time(&t));
// srand(0);
/* For measuring time */
int t0, t1;
const unsigned scale = 20;
const unsigned n_rows_a = 4 * scale;
const unsigned n_cols_a = 3 * scale;
const unsigned n_rows_b = 3 * scale;
const unsigned n_cols_b = 2 * scale;
int __capability *a = malloc(n_rows_a * n_cols_a * sizeof(*a));
int __capability *b = malloc(n_rows_b * n_cols_b * sizeof(*b));
int __capability *c = NULL;
int __capability *d = NULL;
if (!a || !b) {
// printf("Couldn't allocate memory!\n");
while(1);
// system("pause");
// exit(-1);
}
// init_rand(a, n_rows_a, n_cols_a);
// init_rand(b, n_rows_b, n_cols_b);
init_seq(a, n_rows_a, n_cols_a);
init_seq(b, n_rows_b, n_cols_b);
// for (size_t i = 0; i < n_rows_a; i++) {
// for (size_t j = 0; j < n_cols_a; j++) {
// a[i*n_cols_a + j] = i*n_cols_a + j;
// }
// }
// t0 = omp_get_wtime();
c = dot_simple(a, n_rows_a, n_cols_a, b, n_rows_b, n_cols_b);
// t1 = omp_get_wtime();
// printf("Dot Simple: Elapsed time %.3f s\n", t1 - t0);
// // t0 = omp_get_wtime();
d = dot(a, n_rows_a, n_cols_a, b, n_rows_b, n_cols_b);
// t1 = omp_get_wtime();
// printf("Dot: Elapsed time %.3f s\n", t1 - t0);
// if (scale == 1) {
// // printf("Matrix A:\n");
// // print(a, n_rows_a, n_cols_a);
// // // printf("Matrix B:\n");
// // print(b, n_rows_b, n_cols_b);
// // // printf("Matrix C:\n");
// // print(c, n_rows_a, n_cols_b);
// // // printf("Matrix D:\n");
// // print(d, n_rows_a, n_cols_b);
// }
free(a);
free(b);
free(c);
free(d);
// system("pause");
return(0);
}
#endif // MATMUL_1D

View File

@@ -1,10 +1,13 @@
scp ../../start.S home-1:/home/akilan/cheri/output/sdk/bin/ scp ../../start.S home-1:/home/akilan/cheri/output/sdk/bin/
# scp main.c home-1:/home/akilan/cheri/output/sdk/bin/ # scp main.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../malloc.c home-1:/home/akilan/cheri/output/sdk/bin/ scp ../../malloc.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../malloc_test.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../link.ld home-1:/home/akilan/cheri/output/sdk/bin/
scp memaccess.c home-1:/home/akilan/cheri/output/sdk/bin/ scp memaccess.c home-1:/home/akilan/cheri/output/sdk/bin/
ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -Wl,-Ttext=0x80000000 -o testC start.S malloc.c memaccess.c' # ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -Wl,-Ttext=0x80000000 -o testC start.S malloc.c memaccess.c'
ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -DDEFINE_MALLOC -DDEFINE_FREE -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -T link.ld -o testC start.S memaccess.c malloc.c malloc_test.c'
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./llvm-objdump -d testC' # ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./llvm-objdump -d testC'

View File

@@ -27,11 +27,10 @@ All rights reserved.
#define NPAD 7 #define NPAD 7
#define MIN_WSS sizeof(struct l) #define MIN_WSS sizeof(struct l)
#define MAX_WSS 70 #define MAX_WSS 64 //2^32
void free(void * __capability ptr);
void * __capability malloc(size_t size);
void free_test(void * __capability ptr);
void * __capability malloc_test(size_t size);
// struct l{ // struct l{
@@ -262,6 +261,8 @@ void * walk(void * __capability param)
// #ifdef INCTEST // #ifdef INCTEST
// current->pad[0]++; // current->pad[0]++;
// #endif // #endif
current->pad[0]+=current->n->pad[0];
current->pad[0]++;
current=current->n; current=current->n;
} }
@@ -277,7 +278,7 @@ void * walk(void * __capability param)
// printf("%d,%ld,%ld,%ld\n",data->thread_index,data->working_set_size, end-start, data->working_set_size/sizeof(struct l)); // printf("%d,%ld,%ld,%ld\n",data->thread_index,data->working_set_size, end-start, data->working_set_size/sizeof(struct l));
// free(data); free_test(data);
return NULL; return NULL;
} }
@@ -297,7 +298,7 @@ int main(void)
// pthread_t threads[NTHREADS]; // pthread_t threads[NTHREADS];
root=malloc(MAX_WSS/sizeof(struct l) * sizeof(struct l)); root=malloc_test(MAX_WSS/sizeof(struct l) * sizeof(struct l));
for(working_set_size=MIN_WSS;working_set_size<MAX_WSS;working_set_size=working_set_size<<1) for(working_set_size=MIN_WSS;working_set_size<MAX_WSS;working_set_size=working_set_size<<1)
{ {
@@ -330,24 +331,15 @@ int main(void)
// for(i=0;i<NTHREADS;i++) // for(i=0;i<NTHREADS;i++)
// pthread_join(threads[i],NULL); // pthread_join(threads[i],NULL);
// #else // #else
tdata = malloc(sizeof(struct thread_start_data)); tdata = malloc_test(sizeof(struct thread_start_data));
tdata->thread_index=0; tdata->thread_index=0;
tdata->root=root; tdata->root=root;
tdata->working_set_size=working_set_size; tdata->working_set_size=working_set_size;
// clock_t tic2 = clock(); // clock_t tic2 = clock();
for (int i = 0; i < 64000; i++) { for (int i = 0; i < 640000; i++) {
walk(tdata); walk(tdata);
} }
tdata = malloc(sizeof(struct thread_start_data));
tdata->thread_index=0;
tdata->root=root;
tdata->working_set_size=working_set_size;
// clock_t tic2 = clock();
for (int i = 0; i < 64000; i++) {
walk(tdata);
}
// clock_t toc2 = clock(); // clock_t toc2 = clock();
// printf("Elapsed build walk: %f seconds\n", (double)(toc2 - tic2) / CLOCKS_PER_SEC); // printf("Elapsed build walk: %f seconds\n", (double)(toc2 - tic2) / CLOCKS_PER_SEC);
// #endif // #endif
@@ -356,8 +348,10 @@ int main(void)
// printf("-----------------------------------------------"); // printf("-----------------------------------------------");
free(root); free_test(root);
root = NULL; // root = NULL;
// while(1);
return 0; return 0;

View File

@@ -0,0 +1,16 @@
scp ../../start.S home-1:/home/akilan/cheri/output/sdk/bin/
# scp main.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../malloc.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../malloc_test.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../link.ld home-1:/home/akilan/cheri/output/sdk/bin/
scp richards.c home-1:/home/akilan/cheri/output/sdk/bin/
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -Wl,-Ttext=0x80000000 -o testC start.S malloc.c memaccess.c'
ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -DDEFINE_MALLOC -DDEFINE_FREE --gcc-toolchain=/opt/riscv -nostartfiles -fno-builtin-malloc -mcmodel=medany -T link.ld -o testC start.S richards.c malloc.c malloc_test.c'
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./llvm-objdump -d testC'
scp home-1:/home/akilan/cheri/output/sdk/bin/testC ../../../

View File

@@ -0,0 +1,452 @@
// clang-format off
/* C version of the systems programming language benchmark
** Author: M. J. Jordan Cambridge Computer Laboratory.
**
** Modified by: M. Richards, Nov 1996
** to be ANSI C and runnable on 64 bit machines + other minor changes
** Modified by: M. Richards, 20 Oct 1998
** made minor corrections to improve ANSI compliance (suggested
** by David Levine)
** Modified by: Jeremy Singer, 25 May 2022
** adapted to use uintptr_t for compatibility with architectures
** that do not have word-sized pointers (e.g. CHERI)
** also adapted to use Boehm-Demers-Weiser GC instead of system
** malloc, when compiled with -DGC
**
** Compile with, say
**
** gcc -o bench bench.c
**
** or
**
** gcc -o bench100 -Dbench100 bench.c (for a version that obeys
** the main loop 100x more often)
*/
// #include <stdio.h>
#include <stdint.h>
#include <stddef.h>
// #include <stdlib.h>
// #include "harness.h"
// #include "stddefines.h"
// #ifdef GC
// #include "gc.h"
// #define MALLOC GC_MALLOC
// #else
// #define MALLOC malloc
// #endif // GC
// #define malloc tiny_malloc
// #define free tiny_free
void* tiny_malloc(size_t);
void tiny_free(void*);
#ifdef bench100
#define Count 10000*100
#define Qpktcountval 2326410
#define Holdcountval 930563
#else
#define Count 10000
#define Qpktcountval 23246
#define Holdcountval 9297
#endif
#define TRUE 1
#define FALSE 0
#define MAXINT 32767
#define BUFSIZE 3
#define I_IDLE 1
#define I_WORK 2
#define I_HANDLERA 3
#define I_HANDLERB 4
#define I_DEVA 5
#define I_DEVB 6
#define PKTBIT 1
#define WAITBIT 2
#define HOLDBIT 4
#define NOTPKTBIT !1
#define NOTWAITBIT !2
#define NOTHOLDBIT 0XFFFB
#define S_RUN 0
#define S_RUNPKT 1
#define S_WAIT 2
#define S_WAITPKT 3
#define S_HOLD 4
#define S_HOLDPKT 5
#define S_HOLDWAIT 6
#define S_HOLDWAITPKT 7
#define K_DEV 1000
#define K_WORK 1001
struct packet
{
struct packet *p_link;
int p_id;
int p_kind;
int p_a1;
char p_a2[BUFSIZE+1];
};
struct task
{
struct task *t_link;
int t_id;
int t_pri;
struct packet *t_wkq;
int t_state;
struct task *(*t_fn)(struct packet *);
uintptr_t t_v1;
uintptr_t t_v2;
};
char alphabet[28] = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
struct task *tasktab[11] = {(struct task *)10,0,0,0,0,0,0,0,0,0,0};
struct task *tasklist = 0;
struct task *tcb;
long taskid;
uintptr_t v1;
uintptr_t v2;
int qpktcount = 0;
int holdcount = 0;
int tracing = 0;
int layout = 0;
void append(struct packet *pkt, struct packet *ptr);
void createtask(int id,
int pri,
struct packet *wkq,
int state,
struct task *(*fn)(struct packet *),
uintptr_t v1,
uintptr_t v2)
{
struct task *t = (struct task *)tiny_malloc(sizeof(struct task));
tasktab[id] = t;
t->t_link = tasklist;
t->t_id = id;
t->t_pri = pri;
t->t_wkq = wkq;
t->t_state = state;
t->t_fn = fn;
t->t_v1 = v1;
t->t_v2 = v2;
tasklist = t;
}
struct packet *pkt(struct packet *link, int id, int kind)
{
int i;
struct packet *p = (struct packet *)tiny_malloc(sizeof(struct packet));
for (i=0; i<=BUFSIZE; i++)
p->p_a2[i] = 0;
p->p_link = link;
p->p_id = id;
p->p_kind = kind;
p->p_a1 = 0;
return (p);
}
void trace(char a)
{
if ( --layout <= 0 )
{
// printf("\n");
layout = 50;
}
// printf("%c", a);
}
void schedule()
{
while ( tcb != 0 )
{
struct packet *pkt;
struct task *newtcb;
pkt=0;
switch ( tcb->t_state )
{
case S_WAITPKT:
pkt = tcb->t_wkq;
tcb->t_wkq = pkt->p_link;
tcb->t_state = tcb->t_wkq == 0 ? S_RUN : S_RUNPKT;
case S_RUN:
case S_RUNPKT:
taskid = tcb->t_id;
v1 = tcb->t_v1;
v2 = tcb->t_v2;
if (tracing) {
trace(taskid+'0');
}
newtcb = (*(tcb->t_fn))(pkt);
tcb->t_v1 = v1;
tcb->t_v2 = v2;
tcb = newtcb;
break;
case S_WAIT:
case S_HOLD:
case S_HOLDPKT:
case S_HOLDWAIT:
case S_HOLDWAITPKT:
tcb = tcb->t_link;
break;
default:
return;
}
}
}
struct task *wait_task(void)
{
tcb->t_state |= WAITBIT;
return (tcb);
}
struct task *holdself(void)
{
++holdcount;
tcb->t_state |= HOLDBIT;
return (tcb->t_link) ;
}
struct task *findtcb(int id)
{
struct task *t = 0;
if (1<=id && id<=(long)tasktab[0])
t = tasktab[id];
// if (t==0) printf("\nBad task id %d\n", id);
return(t);
}
struct task *release(int id)
{
struct task *t;
t = findtcb(id);
if ( t==0 ) return (0);
t->t_state &= NOTHOLDBIT;
if ( t->t_pri > tcb->t_pri ) return (t);
return (tcb) ;
}
struct task *qpkt(struct packet *pkt)
{
struct task *t;
t = findtcb(pkt->p_id);
if (t==0) return (t);
qpktcount++;
pkt->p_link = 0;
pkt->p_id = taskid;
if (t->t_wkq==0)
{
t->t_wkq = pkt;
t->t_state |= PKTBIT;
if (t->t_pri > tcb->t_pri) return (t);
}
else
{
append(pkt, (struct packet *)&(t->t_wkq));
}
return (tcb);
}
struct task *idlefn(struct packet *pkt)
{
if ( --v2==0 ) return ( holdself() );
if ( (v1&1) == 0 )
{
v1 = ( v1>>1) & MAXINT;
return ( release(I_DEVA) );
}
else
{
v1 = ( (v1>>1) & MAXINT) ^ 0XD008;
return ( release(I_DEVB) );
}
}
struct task *workfn(struct packet *pkt)
{
if ( pkt==0 ) return ( wait_task() );
else
{
int i;
v1 = I_HANDLERA + I_HANDLERB - v1;
pkt->p_id = v1;
pkt->p_a1 = 0;
for (i=0; i<=BUFSIZE; i++)
{
v2++;
if ( v2 > 26 ) v2 = 1;
(pkt->p_a2)[i] = alphabet[v2];
}
return ( qpkt(pkt) );
}
}
struct task *handlerfn(struct packet *pkt)
{
if ( pkt!=0) {
append(pkt, (struct packet *)(pkt->p_kind==K_WORK ? &v1 : &v2));
}
if ( v1!=0 ) {
int count;
struct packet *workpkt = (struct packet *)v1;
count = workpkt->p_a1;
if ( count > BUFSIZE ) {
v1 = (uintptr_t)(((struct packet *)v1)->p_link);
return ( qpkt(workpkt) );
}
if ( v2!=0 ) {
struct packet *devpkt;
devpkt = (struct packet *)v2;
v2 = (uintptr_t)(((struct packet *)v2)->p_link);
devpkt->p_a1 = workpkt->p_a2[count];
workpkt->p_a1 = count+1;
return( qpkt(devpkt) );
}
}
return wait_task();
}
struct task *devfn(struct packet *pkt)
{
if ( pkt==0 )
{
if ( v1==0 ) return ( wait_task() );
pkt = (struct packet *)v1;
v1 = 0;
return ( qpkt(pkt) );
}
else
{
v1 = (uintptr_t)pkt;
if (tracing) trace(pkt->p_a1);
return ( holdself() );
}
}
void append(struct packet *pkt, struct packet *ptr)
{
pkt->p_link = 0;
while ( ptr->p_link ) ptr = ptr->p_link;
ptr->p_link = pkt;
}
int bench() {
struct packet *wkq = 0;
// printf("Bench mark starting\n");
createtask(I_IDLE, 0, wkq, S_RUN, idlefn, 1, Count);
wkq = pkt(0, 0, K_WORK);
wkq = pkt(wkq, 0, K_WORK);
createtask(I_WORK, 1000, wkq, S_WAITPKT, workfn, I_HANDLERA, 0);
wkq = pkt(0, I_DEVA, K_DEV);
wkq = pkt(wkq, I_DEVA, K_DEV);
wkq = pkt(wkq, I_DEVA, K_DEV);
// createtask(I_HANDLERA, 2000, wkq, S_WAITPKT, handlerfn, 0, 0);
// wkq = pkt(0, I_DEVB, K_DEV);
// wkq = pkt(wkq, I_DEVB, K_DEV);
// wkq = pkt(wkq, I_DEVB, K_DEV);
// createtask(I_HANDLERB, 3000, wkq, S_WAITPKT, handlerfn, 0, 0);
// wkq = 0;
// createtask(I_DEVA, 4000, wkq, S_WAIT, devfn, 0, 0);
// createtask(I_DEVB, 5000, wkq, S_WAIT, devfn, 0, 0);
// tcb = tasklist;
// qpktcount = holdcount = 0;
// // printf("Starting\n");
// tracing = FALSE;
// layout = 0;
schedule();
// printf("\nfinished\n");
// if (!(qpktcount == Qpktcountval && holdcount == Holdcountval)) {
// printf("qpkt count = %d holdcount = %d\n", qpktcount, holdcount);
// printf("These results are incorrect");
// exit(1);
// }
// printf("\nend of run\n");
return qpktcount;
}
int inner_loop(int inner) {
int r = 0;
while (inner > 0) {
r += bench();
inner--;
}
return r;
}
int main(int argc, char* argv[])
{
//INITREGULARALLOC();
int iterations = 1;
int warmup = 0;
int inner_iterations = 1;
// parse_argv(argc, argv, &iterations, &warmup, &inner_iterations);
int result = 0;
while (iterations > 0) {
// unsigned long start = microseconds();
result += inner_loop(inner_iterations);
// unsigned long elapsed = microseconds() - start;
// printf("Richards: iterations=1 runtime: %lu%s\n", elapsed, "us");
// print(elapsed);
iterations--;
}
}

View File

@@ -0,0 +1,77 @@
/* The Computer Language Benchmarks Game
* https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
*
* Contributed by Mr Ledrug
* https://github.com/dstogov/c-benchmarks
* spectral-norm
* Algorithm lifted from Intel Fortran #2 code by Steve Decker et al.
*/
// #include <stdio.h>
// #include <math.h>
#include <stddef.h>
#include <stdint.h>
void* tiny_malloc(size_t);
void tiny_free(void*);
static inline int A(int i, int j) {
return ((i+j) * (i+j+1) / 2 + i + 1);
}
double dot(double * v, double * u, int n) {
int i;
double sum = 0;
for (i = 0; i < n; i++)
sum += v[i] * u[i];
return sum;
}
void mult_Av(double * v, double * out, int n) {
int i, j;
double sum;
for (i = 0; i < n; i++) {
for (sum = j = 0; j < n; j++)
sum += v[j] / A(i,j);
out[i] = sum;
}
}
void mult_Atv(double * v, double * out,int n) {
int i, j;
double sum;
for (i = 0; i < n; i++) {
for (sum = j = 0; j < n; j++)
sum += v[j] / A(j,i);
out[i] = sum;
}
}
double *tmp;
void mult_AtAv(double *v, double *out,int n) {
//mult_Av(v, tmp, n);
mult_Atv(tmp, out, n);
}
int main(void) {
int n = 1;
// if (n <= 0) n = 2000;
double *u, *v;
u = tiny_malloc(n * sizeof(double));
v = tiny_malloc(n * sizeof(double));
tmp = tiny_malloc(n * sizeof(double));
int i;
for (i = 0; i < n; i++) u[i] = 1;
for (i = 0; i < 10; i++) {
mult_AtAv(u, v, n);
mult_AtAv(v, u, n);
}
// printf("%.9f\n", sqrt(dot(u,v, n) / dot(v,v,n)));
return 0;
}

View File

@@ -0,0 +1,19 @@
# scp ../../start.S home-1:/home/akilan/cheri/output/sdk/bin/
# # scp main.c home-1:/home/akilan/cheri/output/sdk/bin/
# scp ../../malloc.c home-1:/home/akilan/cheri/output/sdk/bin/
# scp ../../malloc_test.c home-1:/home/akilan/cheri/output/sdk/bin/
# scp ../../link.ld home-1:/home/akilan/cheri/output/sdk/bin/
scp barnes.c home-1:/home/akilan/cheri/output/sdk/bin/
# scp barnes_hut.h home-1:/home/akilan/cheri/output/sdk/bin/
scp test.c home-1:/home/akilan/cheri/output/sdk/bin/
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -Wl,-Ttext=0x80000000 -o testC start.S malloc.c memaccess.c'
ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -DDEFINE_MALLOC -DDEFINE_FREE -nostdlib -nostartfiles -fno-builtin-malloc --gcc-toolchain=/opt/riscv -mcmodel=medany -T link.ld -o testC start.S barnes.c malloc.c malloc_test.c'
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./llvm-objdump -d testC'
scp home-1:/home/akilan/cheri/output/sdk/bin/testC ../../../

Binary file not shown.

View File

@@ -0,0 +1,38 @@
#include <stdio.h>
#include <math.h>
// double PI = 3.141592653589793;
// double wrap_angle(double x) {
// while (x > PI) x -= 2*PI;
// while (x < -PI) x += 2*PI;
// return x;
// }
// double my_sin(double x) {
// x = wrap_angle(x);
// double x2 = x * x;
// return x
// - (x * x2) / 6
// + (x * x2 * x2) / 120
// - (x * x2 * x2 * x2) / 5040;
// }
int my_cos(int x) {
x *= x;
return 1 - x/2 * (1 - x/12 * (1 - x/30 * (1 - x/56 * (1 - x/90))));
}
int main(void) {
// const double PI = 3.141592653589793;
int x = my_cos(3);
// printf("%f\n", cos(3));
// printf("%f\n", cos(-3));
// printf("%f\n", cos(0));
// printf("%f\n", cos(PI));
// printf("%f\n", cos(PI / 2.0));
return 0;
}

View File

@@ -1,10 +1,13 @@
scp ../../start.S home-1:/home/akilan/cheri/output/sdk/bin/ scp ../../start.S home-1:/home/akilan/cheri/output/sdk/bin/
# scp main.c home-1:/home/akilan/cheri/output/sdk/bin/ # scp main.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../malloc.c home-1:/home/akilan/cheri/output/sdk/bin/ scp ../../malloc.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../malloc_test.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../link.ld home-1:/home/akilan/cheri/output/sdk/bin/
scp glibc.c home-1:/home/akilan/cheri/output/sdk/bin/ scp glibc.c home-1:/home/akilan/cheri/output/sdk/bin/
ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -Wl,-Ttext=0x80000000 -o testC start.S malloc.c glibc.c' # ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -Wl,-Ttext=0x80000000 -o testC start.S malloc.c memaccess.c'
ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -DDEFINE_MALLOC -DDEFINE_FREE -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -T link.ld -o testC start.S glibc.c malloc.c malloc_test.c'
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./llvm-objdump -d testC' # ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./llvm-objdump -d testC'

View File

@@ -216,7 +216,7 @@ int main (void)
// if (argc > 2 || size <= 0) // if (argc > 2 || size <= 0)
// usage (argv[0]); // usage (argv[0]);
// bench (size); bench (size);
// bench (2*size); // bench (2*size);
// bench (4*size); // bench (4*size);
// bench (8*size); // bench (8*size);

View File

@@ -0,0 +1,16 @@
scp ../../start.S home-1:/home/akilan/cheri/output/sdk/bin/
# scp main.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../malloc.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../malloc_test.c home-1:/home/akilan/cheri/output/sdk/bin/
scp ../../link.ld home-1:/home/akilan/cheri/output/sdk/bin/
scp kmeans.c home-1:/home/akilan/cheri/output/sdk/bin/
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -Wl,-Ttext=0x80000000 -o testC start.S malloc.c memaccess.c'
ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -DDEFINE_MALLOC -DDEFINE_FREE -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -T link.ld -o testC start.S kmeans.c malloc.c malloc_test.c'
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./llvm-objdump -d testC'
scp home-1:/home/akilan/cheri/output/sdk/bin/testC ../../../

View File

@@ -0,0 +1,123 @@
// #include <cheri_init_globals.h>
// #include <cheritypes.h>
#include <cheriintrin.h>
#include <stdint.h>
#include <stddef.h>
#include <stdint.h>
#include <float.h>
// #include <math.h>
/* --- Simple Bare-Metal CHERI Malloc --- */
// #define HEAP_SIZE 0x10000
// static uint8_t raw_heap[HEAP_SIZE] __attribute__((aligned(16)));
// static size_t heap_ptr = 0;
// void* cheri_malloc(size_t size) {
// // Ensure 16-byte alignment for CHERI capability representability
// size = (size + 15) & ~15;
// if (heap_ptr + size > HEAP_SIZE) return NULL;
// // Get a capability to the heap slice
// void *ptr = cheri_get_base(&raw_heap[heap_ptr]);
// // Set strict bounds on the returned capability
// ptr = cheri_set_bounds(ptr, size);
// heap_ptr += size;
// return ptr;
// }
void free(void * __capability ptr);
void * __capability malloc(size_t size);
/* --- K-Means Hybrid Structures --- */
typedef struct {
float x, y;
} Point;
typedef struct {
float x, y;
int count;
} Centroid;
float get_distance(Point p, Centroid c) {
float dx = p.x - c.x;
float dy = p.y - c.y;
return (dx * dx) + (dy * dy); // Squared Euclidean
}
/* --- Main Logic --- */
void run_kmeans(Point * __capability points, int num_points, int k, int iterations) {
// Allocate centroids using our CHERI-bounded malloc
Centroid * __capability centroids = (Centroid * __capability)malloc(sizeof(Centroid) * k);
int * __capability assignments = (int * __capability)malloc(sizeof(int) * num_points);
if (!centroids || !assignments) return;
// Initialize Centroids (Simple sequential pick)
for (int i = 0; i < k; i++) {
centroids[i].x = points[i].x;
centroids[i].y = points[i].y;
}
for (int iter = 0; iter < iterations; iter++) {
// 1. Assignment Step
for (int i = 0; i < num_points; i++) {
float min_dist = FLT_MAX;
int best_cluster = 0;
for (int j = 0; j < k; j++) {
float d = get_distance(points[i], centroids[j]);
if (d < min_dist) {
min_dist = d;
best_cluster = j;
}
}
assignments[i] = best_cluster;
}
// 2. Update Step
for (int i = 0; i < k; i++) {
centroids[i].x = 0;
centroids[i].y = 0;
centroids[i].count = 0;
}
for (int i = 0; i < num_points; i++) {
int cluster = assignments[i];
centroids[cluster].x += points[i].x;
centroids[cluster].y += points[i].y;
centroids[cluster].count++;
}
for (int i = 0; i < k; i++) {
if (centroids[i].count > 0) {
centroids[i].x /= centroids[i].count;
centroids[i].y /= centroids[i].count;
}
}
}
}
int main() {
int n = 10;
int k = 3;
// Allocate point data on our CHERI heap
Point * __capability data = (Point * __capability)malloc(sizeof(Point) * n);
if (data) {
// Mock data initialization
for(int i = 0; i < n; i++) {
data[i].x = (float)(i % 10);
data[i].y = (float)(i / 10);
}
run_kmeans(data, n, k, 10);
}
return 0;
}

View File

@@ -1,7 +1,9 @@
# Send assembler file to remote machine to run # Send assembler file to remote machine to run
scp start.S home-1:/home/akilan/cheri/output/sdk/bin/ scp start.S home-1:/home/akilan/cheri/output/sdk/bin/
scp main.c home-1:/home/akilan/cheri/output/sdk/bin/ scp main.c home-1:/home/akilan/cheri/output/sdk/bin/
scp malloc_test.c home-1:/home/akilan/cheri/output/sdk/bin/
scp malloc.c home-1:/home/akilan/cheri/output/sdk/bin/ scp malloc.c home-1:/home/akilan/cheri/output/sdk/bin/
scp link.ld home-1:/home/akilan/cheri/output/sdk/bin/
# scp cheri.S home:/home/akilan/cheri/output/sdk/bin/ # scp cheri.S home:/home/akilan/cheri/output/sdk/bin/
@@ -13,10 +15,10 @@ scp malloc.c home-1:/home/akilan/cheri/output/sdk/bin/
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -nostdlib -nostartfiles -Wl,-Ttext=0x80000000 -o testC start.S main.c' # ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -nostdlib -nostartfiles -Wl,-Ttext=0x80000000 -o testC start.S main.c'
# Malloc test implementation # Malloc test implementation
ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -Wl,-Ttext=0x80000000 -o testC start.S main.c malloc.c' ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -DDEFINE_MALLOC -DDEFINE_FREE -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -T link.ld -o testC start.S main.c malloc.c malloc_test.c'
# Disassembly ouput # Disassembly ouput
ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./llvm-objdump -d testC' # ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./llvm-objdump -d testC'
# Copy file back for testing # Copy file back for testing
scp home-1:/home/akilan/cheri/output/sdk/bin/testC ../ scp home-1:/home/akilan/cheri/output/sdk/bin/testC ../

View File

@@ -0,0 +1,19 @@
OUTPUT_ARCH( "riscv" )
ENTRY(_start)
SECTIONS
{
. = 0x80000000;
.text.init : { *(.text.init) }
. = ALIGN(0x1000);
.tohost : { *(.tohost) }
. = ALIGN(0x1000);
.text : { *(.text) }
. = ALIGN(0x1000);
.data : { *(.data) }
.bss : { *(.bss) }
_end = .;
__malloc_start = .;
. = . + 0x10000;
}

View File

@@ -7,6 +7,8 @@
#include "riscv_test.h" #include "riscv_test.h"
// void free(void *ptr);
// void *malloc(size_t size);
void free(void * __capability ptr); void free(void * __capability ptr);
void * __capability malloc(size_t size); void * __capability malloc(size_t size);
@@ -61,35 +63,37 @@ void test() {
// } // }
int main(void) { int main(void) {
char * __capability a = malloc(30); int * __capability a = malloc(30);
char * __capability b = malloc(16); char * __capability b = malloc(16);
// if (!a || !b) return -1; // if (!a || !b) return -1;
a[0] = 'A'; a[0] = 1;
a[1] = 'C'; a[1] = 'C';
b[0] = 'B'; b[0] = 'B';
b[10] = 'D';
// This will fault (out-of-bounds) // This will fault (out-of-bounds)
// a[20] = 'X'; // a[20] = 'X';
if (a[1] != 'C') { if (a[0] != 1) {
while (1); while (1);
} }
if (b[0] != 'B') { if (b[10] != 'D') {
while (1); while (1);
} }
free(&b); free(a);
b = NULL; // b = NULL;
if (b[0] == 'B') { // if (b[0] == 'B') {
while (1); // while (1);
} // }
char * __capability c = malloc(16); // char * __capability c = malloc(16);
// if (c[0] != 'B') { // if (c[0] != 'B') {
// while (1); // while (1);

View File

@@ -13,20 +13,42 @@
// | | (Distance 1 between address) // | | (Distance 1 between address)
// [1, 2, 3. ....... n] -> virtual // [1, 2, 3. ....... n] -> virtual
#define HEAP_SIZE 65536 // 64 KB heap void* tiny_malloc(size_t);
void tiny_free(void*);
#define PHYS_BASE 0x80000000 #define ALIGN 16
#define VIRT_BASE 0xFFFFFFFF80000000
static char heap[HEAP_SIZE]; // #define HEAP_SIZE 65536 // 64 KB heap
static size_t bump = 0;
static void * __capability free_list = NULL; // #define PHYS_BASE 0x80000000
// #define VIRT_BASE 0xFFFFFFFF80000000
typedef struct free_node { // static char heap[HEAP_SIZE];
void * __capability next; // static size_t bump = 0;
} free_node_t;
// static void * __capability free_list = NULL;
// typedef struct free_node {
// void * __capability next;
// } free_node_t;
static uintptr_t next_virtual = 0x10000000;
uintptr_t compute_physical_base(size_t size) {
// 1. Determine the required alignment for this size in CHERI
size_t mask = cheri_representable_alignment_mask(size);
// 2. Round up the current next_virtual to the required alignment
uintptr_t base = (next_virtual + ~mask) & mask;
// 3. Ensure the length itself is representable
size_t representable_len = cheri_representable_length(size);
// 4. Update the global pointer for the next call
next_virtual = base + representable_len;
return base;
}
// Add delta value for TLB translation // Add delta value for TLB translation
@@ -45,53 +67,91 @@ static inline void * __capability add_delta(void * __capability cap, int offset)
} }
// Malloc wrapper
// Malloc wrapper
// void * __capability malloc(size_t size) {
// uintptr_t raw = (uintptr_t)tiny_malloc(size);
// // void *__capability cap = (void *__capability)raw;
// void *__capability cap = cheri_ddc_get();
// // // Set address from raw pointer
// cap = cheri_address_set(cap, raw);
// int delta = 12;
// delta = (delta + ALIGN - 1) & ~(ALIGN - 1);
// cap = add_delta(cap, delta);
// size_t aligned = cheri_representable_length(size);
// cap = cheri_bounds_set(cap, aligned);
// // // Align to 8 bytes (important for capability safety)
// // size = (size + 7) & ~7;
// // if (bump + size > HEAP_SIZE)
// // return NULL;
// // void * __capability base = cheri_ddc_get();
// // uintptr_t addr = (uintptr_t)(heap + bump);
// // // Create capability to this region
// // void * __capability cap = cheri_address_set(base, addr);
// // // Enforce bounds (this is the key CHERI feature)
// // cap = cheri_bounds_set(cap, size);
// // // Hard-coded delta value
// // cap = add_delta(cap, 10);
// // bump += size;
// return cap;
// }
void * __capability malloc(size_t size) { void * __capability malloc(size_t size) {
void * phys_ptr = tiny_malloc(size);
if (!phys_ptr) return NULL;
// Align to 8 bytes (important for capability safety) uintptr_t raw_phys = (uintptr_t)phys_ptr;
size = (size + 7) & ~7; intptr_t p_base = compute_physical_base(size);
intptr_t delta = p_base - (intptr_t)raw_phys;
if (bump + size > HEAP_SIZE) void * __capability cap = cheri_ddc_get();
return NULL; cap = cheri_address_set(cap, raw_phys);
void * __capability base = cheri_ddc_get(); cap = add_delta(cap, (int)delta);
uintptr_t addr = (uintptr_t)(heap + bump); size_t aligned_size = cheri_representable_length(size);
cap = cheri_bounds_set(cap, aligned_size);
// Create capability to this region
void * __capability cap = cheri_address_set(base, addr);
// Enforce bounds (this is the key CHERI feature)
cap = cheri_bounds_set(cap, size);
// Hard-coded delta value
cap = add_delta(cap, 10);
bump += size;
return cap; return cap;
} }
void bump_reset(void) { // void bump_reset(void) {
bump = 0; // bump = 0;
} // }
// Can only free if it's in a stack // Free wrapper
// Need to write a free †hat can work
// in any sequence
// In regular malloc the freelist
// is maintained from mmap.
void free(void * __capability ptr) { void free(void * __capability ptr) {
if (!ptr) return; // if (!ptr) return;
uintptr_t addr = cheri_address_get(ptr); // uintptr_t addr = cheri_address_get(ptr);
size_t size = cheri_length_get(ptr); // size_t size = cheri_length_get(ptr);
// Check if this is the most recent allocation // // Check if this is the most recent allocation
if ((char *)addr + size == heap + bump) { // if ((char *)addr + size == heap + bump) {
bump -= size; // bump -= size;
} // }
// *ptr = NULL; // Extract raw address from capability
void *raw = (void *)cheri_address_get(ptr);
tiny_free(raw);
} }
// Quick tests // Quick tests

View File

@@ -0,0 +1,97 @@
#include <stdint.h>
#include <stddef.h>
#define HEAP_SIZE 0x10000
extern uint8_t __malloc_start;
static uint8_t* heap = &__malloc_start;
typedef struct block {
size_t size;
int free;
struct block* next;
} block;
static block* free_list;
static intptr_t next_virtual = 0x10000000;
intptr_t compute_virtual_base() {
intptr_t v = next_virtual;
next_virtual += 0x1000; // or size
return v;
}
void mem_init() {
free_list = (block*)heap;
free_list->size = HEAP_SIZE - sizeof(block);
free_list->free = 1;
free_list->next = NULL;
}
void* my_malloc(size_t size) {
block* curr = free_list;
while (curr) {
if (curr->free && curr->size >= size) {
if (curr->size > size + sizeof(block)) {
block* newb =
(block*)((uint8_t*)curr + sizeof(block) + size);
newb->size = curr->size - size - sizeof(block);
newb->free = 1;
newb->next = curr->next;
curr->next = newb;
curr->size = size;
}
curr->free = 0;
// TODO: lift off delta to a earlier stage
void* phys = (uint8_t*)curr + sizeof(block);
// compute delta for this allocation
intptr_t delta = compute_virtual_base() - (intptr_t)phys;
// apply hardware instruction assumption:
asm volatile("add_delta %0, %0, %1"
: "+r"(phys)
: "r"(delta));
return phys;
}
curr = curr->next;
}
return NULL;
}
void my_free(void* ptr) {
if (!ptr) return;
// delta is guaranteed 0 → treat pointer as physical
block* b = (block*)((uint8_t*)ptr - sizeof(block));
b->free = 1;
// coalesce adjacent free blocks (pure physical heap logic)
block* curr = free_list;
while (curr && curr->next) {
if (curr->free && curr->next->free) {
curr->size += sizeof(block) + curr->next->size;
curr->next = curr->next->next;
} else {
curr = curr->next;
}
}
}

View File

@@ -0,0 +1,601 @@
// https://github.com/32bitmicro/newlib-nano-1.0/blob/master/newlib/libc/machine/xstormy16/tiny-malloc.c
/* A replacement malloc with:
- Much reduced code size;
- Smaller RAM footprint;
- The ability to handle downward-growing heaps;
but
- Slower;
- Probably higher memory fragmentation;
- Doesn't support threads (but, if it did support threads,
it wouldn't need a global lock, only a compare-and-swap instruction);
- Assumes the maximum alignment required is the alignment of a pointer;
- Assumes that memory is already there and doesn't need to be allocated.
* Synopsis of public routines
malloc(size_t n);
Return a pointer to a newly allocated chunk of at least n bytes, or null
if no space is available.
free(void* p);
Release the chunk of memory pointed to by p, or no effect if p is null.
realloc(void* p, size_t n);
Return a pointer to a chunk of size n that contains the same data
as does chunk p up to the minimum of (n, p's size) bytes, or null
if no space is available. The returned pointer may or may not be
the same as p. If p is null, equivalent to malloc. Unless the
#define REALLOC_ZERO_BYTES_FREES below is set, realloc with a
size argument of zero (re)allocates a minimum-sized chunk.
memalign(size_t alignment, size_t n);
Return a pointer to a newly allocated chunk of n bytes, aligned
in accord with the alignment argument, which must be a power of
two. Will fail if 'alignment' is too large.
calloc(size_t unit, size_t quantity);
Returns a pointer to quantity * unit bytes, with all locations
set to zero.
cfree(void* p);
Equivalent to free(p).
malloc_trim(size_t pad);
Release all but pad bytes of freed top-most memory back
to the system. Return 1 if successful, else 0.
malloc_usable_size(void* p);
Report the number usable allocated bytes associated with allocated
chunk p. This may or may not report more bytes than were requested,
due to alignment and minimum size constraints.
malloc_stats();
Prints brief summary statistics on stderr.
mallinfo()
Returns (by copy) a struct containing various summary statistics.
mallopt(int parameter_number, int parameter_value)
Changes one of the tunable parameters described below. Returns
1 if successful in changing the parameter, else 0. Actually, returns 0
always, as no parameter can be changed.
*/
#ifdef __xstormy16__
#define MALLOC_DIRECTION -1
#endif
#ifndef MALLOC_DIRECTION
#define MALLOC_DIRECTION 1
#endif
#include <stddef.h>
void* tiny_malloc(size_t);
void tiny_free(void*);
void* realloc(void*, size_t);
void* memalign(size_t, size_t);
void* valloc(size_t);
void* pvalloc(size_t);
void* calloc(size_t, size_t);
void cfree(void*);
int malloc_trim(size_t);
size_t malloc_usable_size(void*);
void malloc_stats(void);
int mallopt(int, int);
struct mallinfo mallinfo(void);
typedef struct freelist_entry {
size_t size;
struct freelist_entry *next;
} *fle;
extern void * __malloc_end;
extern fle __malloc_freelist;
/* Return the number of bytes that need to be added to X to make it
aligned to an ALIGN boundary. ALIGN must be a power of 2. */
#define M_ALIGN(x, align) (-(size_t)(x) & ((align) - 1))
/* Return the number of bytes that need to be subtracted from X to make it
aligned to an ALIGN boundary. ALIGN must be a power of 2. */
#define M_ALIGN_SUB(x, align) ((size_t)(x) & ((align) - 1))
extern char *__malloc_start;
/* This is the minimum gap allowed between __malloc_end and the top of
the stack. This is only checked for when __malloc_end is
decreased; if instead the stack grows into the heap, silent data
corruption will result. */
#define MALLOC_MINIMUM_GAP 32
#ifdef __xstormy16__
register void * stack_pointer asm ("r15");
#define MALLOC_LIMIT stack_pointer
#else
#define MALLOC_LIMIT __builtin_frame_address (0)
#endif
#if MALLOC_DIRECTION < 0
#define CAN_ALLOC_P(required) \
(((size_t) __malloc_end - (size_t)MALLOC_LIMIT \
- MALLOC_MINIMUM_GAP) >= (required))
#else
#define CAN_ALLOC_P(required) \
(((size_t)MALLOC_LIMIT - (size_t) __malloc_end \
- MALLOC_MINIMUM_GAP) >= (required))
#endif
/* real_size is the size we actually have to allocate, allowing for
overhead and alignment. */
#define REAL_SIZE(sz) \
((sz) < sizeof (struct freelist_entry) - sizeof (size_t) \
? sizeof (struct freelist_entry) \
: sz + sizeof (size_t) + M_ALIGN(sz, sizeof (size_t)))
#ifdef DEFINE_MALLOC
void * __malloc_end = &__malloc_start;
fle __malloc_freelist;
void *
tiny_malloc (size_t sz)
{
fle *nextfree;
fle block;
/* real_size is the size we actually have to allocate, allowing for
overhead and alignment. */
size_t real_size = REAL_SIZE (sz);
/* Look for the first block on the freelist that is large enough. */
for (nextfree = &__malloc_freelist;
*nextfree;
nextfree = &(*nextfree)->next)
{
block = *nextfree;
if (block->size >= real_size)
{
/* If the block found is just the right size, remove it from
the free list. Otherwise, split it. */
if (block->size < real_size + sizeof (struct freelist_entry))
{
*nextfree = block->next;
return (void *)&block->next;
}
else
{
size_t newsize = block->size - real_size;
fle newnext = block->next;
*nextfree = (fle)((size_t)block + real_size);
(*nextfree)->size = newsize;
(*nextfree)->next = newnext;
goto done;
}
}
/* If this is the last block on the freelist, and it was too small,
enlarge it. */
if (! block->next
&& __malloc_end == (void *)((size_t)block + block->size))
{
size_t moresize = real_size - block->size;
if (! CAN_ALLOC_P (moresize))
return NULL;
*nextfree = NULL;
if (MALLOC_DIRECTION < 0)
{
block = __malloc_end = (void *)((size_t)block - moresize);
}
else
{
__malloc_end = (void *)((size_t)block + real_size);
}
goto done;
}
}
/* No free space at the end of the free list. Allocate new space
and use that. */
if (! CAN_ALLOC_P (real_size))
return NULL;
if (MALLOC_DIRECTION > 0)
{
block = __malloc_end;
__malloc_end = (void *)((size_t)__malloc_end + real_size);
}
else
{
block = __malloc_end = (void *)((size_t)__malloc_end - real_size);
}
done:
block->size = real_size;
// TODO: return as bounds
return (void *)&block->next;
}
#endif
#ifdef DEFINE_FREE
void
tiny_free (void *block_p)
{
fle *nextfree;
fle block = (fle)((size_t) block_p - offsetof (struct freelist_entry, next));
if (block_p == NULL)
return;
/* Look on the freelist to see if there's a free block just before
or just after this block. */
for (nextfree = &__malloc_freelist;
*nextfree;
nextfree = &(*nextfree)->next)
{
fle thisblock = *nextfree;
if ((size_t)thisblock + thisblock->size == (size_t) block)
{
thisblock->size += block->size;
if (MALLOC_DIRECTION > 0
&& thisblock->next
&& (size_t) block + block->size == (size_t) thisblock->next)
{
thisblock->size += thisblock->next->size;
thisblock->next = thisblock->next->next;
}
return;
}
else if ((size_t) thisblock == (size_t) block + block->size)
{
if (MALLOC_DIRECTION < 0
&& thisblock->next
&& (size_t) block == ((size_t) thisblock->next
+ thisblock->next->size))
{
*nextfree = thisblock->next;
thisblock->next->size += block->size + thisblock->size;
}
else
{
block->size += thisblock->size;
block->next = thisblock->next;
*nextfree = block;
}
return;
}
else if ((MALLOC_DIRECTION > 0
&& (size_t) thisblock > (size_t) block)
|| (MALLOC_DIRECTION < 0
&& (size_t) thisblock < (size_t) block))
break;
}
block->next = *nextfree;
*nextfree = block;
return;
}
#endif
#ifdef DEFINE_REALLOC
void *
realloc (void *block_p, size_t sz)
{
fle block = (fle)((size_t) block_p - offsetof (struct freelist_entry, next));
size_t real_size = REAL_SIZE (sz);
size_t old_real_size;
if (block_p == NULL)
return malloc (sz);
old_real_size = block->size;
/* Perhaps we need to allocate more space. */
if (old_real_size < real_size)
{
void *result;
size_t old_size = old_real_size - sizeof (size_t);
/* Need to allocate, copy, and free. */
result = malloc (sz);
if (result == NULL)
return NULL;
memcpy (result, block_p, old_size < sz ? old_size : sz);
free (block_p);
return result;
}
/* Perhaps we can free some space. */
if (old_real_size - real_size >= sizeof (struct freelist_entry))
{
fle newblock = (fle)((size_t)block + real_size);
block->size = real_size;
newblock->size = old_real_size - real_size;
free (&newblock->next);
}
return block_p;
}
#endif
#ifdef DEFINE_CALLOC
void *
calloc (size_t n, size_t elem_size)
{
void *result;
size_t sz = n * elem_size;
result = malloc (sz);
if (result != NULL)
memset (result, 0, sz);
return result;
}
#endif
#ifdef DEFINE_CFREE
void
cfree (void *p)
{
free (p);
}
#endif
#ifdef DEFINE_MEMALIGN
void *
memalign (size_t align, size_t sz)
{
fle *nextfree;
fle block;
/* real_size is the size we actually have to allocate, allowing for
overhead and alignment. */
size_t real_size = REAL_SIZE (sz);
/* Some sanity checking on 'align'. */
if ((align & (align - 1)) != 0
|| align <= 0)
return NULL;
/* Look for the first block on the freelist that is large enough. */
/* One tricky part is this: We want the result to be a valid pointer
to free. That means that there has to be room for a size_t
before the block. If there's additional space before the block,
it should go on the freelist, or it'll be lost---we could add it
to the size of the block before it in memory, but finding the
previous block is expensive. */
for (nextfree = &__malloc_freelist;
;
nextfree = &(*nextfree)->next)
{
size_t before_size;
size_t old_size;
/* If we've run out of free blocks, allocate more space. */
if (! *nextfree)
{
old_size = real_size;
if (MALLOC_DIRECTION < 0)
{
old_size += M_ALIGN_SUB (((size_t)__malloc_end
- old_size + sizeof (size_t)),
align);
if (! CAN_ALLOC_P (old_size))
return NULL;
block = __malloc_end = (void *)((size_t)__malloc_end - old_size);
}
else
{
block = __malloc_end;
old_size += M_ALIGN ((size_t)__malloc_end + sizeof (size_t),
align);
if (! CAN_ALLOC_P (old_size))
return NULL;
__malloc_end = (void *)((size_t)__malloc_end + old_size);
}
*nextfree = block;
block->size = old_size;
block->next = NULL;
}
else
{
block = *nextfree;
old_size = block->size;
}
before_size = M_ALIGN (&block->next, align);
if (before_size != 0)
before_size = sizeof (*block) + M_ALIGN (&(block+1)->next, align);
/* If this is the last block on the freelist, and it is too small,
enlarge it. */
if (! block->next
&& old_size < real_size + before_size
&& __malloc_end == (void *)((size_t)block + block->size))
{
if (MALLOC_DIRECTION < 0)
{
size_t moresize = real_size - block->size;
moresize += M_ALIGN_SUB ((size_t)&block->next - moresize, align);
if (! CAN_ALLOC_P (moresize))
return NULL;
block = __malloc_end = (void *)((size_t)block - moresize);
block->next = NULL;
block->size = old_size = old_size + moresize;
before_size = 0;
}
else
{
if (! CAN_ALLOC_P (before_size + real_size - block->size))
return NULL;
__malloc_end = (void *)((size_t)block + before_size + real_size);
block->size = old_size = before_size + real_size;
}
/* Two out of the four cases below will now be possible; which
two depends on MALLOC_DIRECTION. */
}
if (old_size >= real_size + before_size)
{
/* This block will do. If there needs to be space before it,
split the block. */
if (before_size != 0)
{
fle old_block = block;
old_block->size = before_size;
block = (fle)((size_t)block + before_size);
/* If there's no space after the block, we're now nearly
done; just make a note of the size required.
Otherwise, we need to create a new free space block. */
if (old_size - before_size
<= real_size + sizeof (struct freelist_entry))
{
block->size = old_size - before_size;
return (void *)&block->next;
}
else
{
fle new_block;
new_block = (fle)((size_t)block + real_size);
new_block->size = old_size - before_size - real_size;
if (MALLOC_DIRECTION > 0)
{
new_block->next = old_block->next;
old_block->next = new_block;
}
else
{
new_block->next = old_block;
*nextfree = new_block;
}
goto done;
}
}
else
{
/* If the block found is just the right size, remove it from
the free list. Otherwise, split it. */
if (old_size <= real_size + sizeof (struct freelist_entry))
{
*nextfree = block->next;
return (void *)&block->next;
}
else
{
size_t newsize = old_size - real_size;
fle newnext = block->next;
*nextfree = (fle)((size_t)block + real_size);
(*nextfree)->size = newsize;
(*nextfree)->next = newnext;
goto done;
}
}
}
}
done:
block->size = real_size;
return (void *)&block->next;
}
#endif
#ifdef DEFINE_VALLOC
void *
valloc (size_t sz)
{
return memalign (128, sz);
}
#endif
#ifdef DEFINE_PVALLOC
void *
pvalloc (size_t sz)
{
return memalign (128, sz + M_ALIGN (sz, 128));
}
#endif
#ifdef DEFINE_MALLINFO
#include "malloc.h"
struct mallinfo
mallinfo (void)
{
struct mallinfo r;
fle fr;
size_t free_size;
size_t total_size;
size_t free_blocks;
memset (&r, 0, sizeof (r));
free_size = 0;
free_blocks = 0;
for (fr = __malloc_freelist; fr; fr = fr->next)
{
free_size += fr->size;
free_blocks++;
if (! fr->next)
{
int atend;
if (MALLOC_DIRECTION > 0)
atend = (void *)((size_t)fr + fr->size) == __malloc_end;
else
atend = (void *)fr == __malloc_end;
if (atend)
r.keepcost = fr->size;
}
}
if (MALLOC_DIRECTION > 0)
total_size = (char *)__malloc_end - (char *)&__malloc_start;
else
total_size = (char *)&__malloc_start - (char *)__malloc_end;
#ifdef DEBUG
/* Fixme: should walk through all the in-use blocks and see if
they're valid. */
#endif
r.arena = total_size;
r.fordblks = free_size;
r.uordblks = total_size - free_size;
r.ordblks = free_blocks;
return r;
}
#endif
#ifdef DEFINE_MALLOC_STATS
#include "malloc.h"
#include <stdio.h>
void
malloc_stats(void)
{
struct mallinfo i;
FILE *fp;
fp = stderr;
i = mallinfo();
fprintf (fp, "malloc has reserved %u bytes between %p and %p\n",
i.arena, &__malloc_start, __malloc_end);
fprintf (fp, "there are %u bytes free in %u chunks\n",
i.fordblks, i.ordblks);
fprintf (fp, "of which %u bytes are at the end of the reserved space\n",
i.keepcost);
fprintf (fp, "and %u bytes are in use.\n", i.uordblks);
}
#endif
#ifdef DEFINE_MALLOC_USABLE_SIZE
size_t
malloc_usable_size (void *block_p)
{
fle block = (fle)((size_t) block_p - offsetof (struct freelist_entry, next));
return block->size - sizeof (size_t);
}
#endif
#ifdef DEFINE_MALLOPT
int
mallopt (int n, int v)
{
(void)n; (void)v;
return 0;
}
#endif

Binary file not shown.

View File

@@ -0,0 +1 @@
*.txt

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -60,12 +60,12 @@ import TlbTypes::*;
import SynthParam::*; import SynthParam::*;
import VerificationPacket::*; import VerificationPacket::*;
import Performance::*; import Performance::*;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*; import PerformanceMonitor::*;
import BlueUtils::*; import BlueUtils::*;
import StatCounters::*; import StatCounters::*;
import GenerateHPMVector::*; import GenerateHPMVector::*;
`endif // `endif
import HasSpecBits::*; import HasSpecBits::*;
import Exec::*; import Exec::*;
import FetchStage::*; import FetchStage::*;
@@ -212,10 +212,10 @@ interface Core;
interface Vector #(SupSize, Get #(Trace_Data2)) v_to_TV; interface Vector #(SupSize, Get #(Trace_Data2)) v_to_TV;
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method Action events_llc(EventsLL events); method Action events_llc(EventsLL events);
method Action events_tgc(EventsTGC events); method Action events_tgc(EventsTGC events);
`endif // `endif
endinterface endinterface
// fixpoint to instantiate modules // fixpoint to instantiate modules
@@ -268,9 +268,9 @@ module mkCore#(CoreId coreId)(Core);
Vector #(SupSize, FIFOF #(Trace_Data2)) v_f_to_TV <- replicateM (mkFIFOF); Vector #(SupSize, FIFOF #(Trace_Data2)) v_f_to_TV <- replicateM (mkFIFOF);
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
Array #(Reg #(EventsCore)) hpm_core_events <- mkDRegOR (2, unpack (0)); Array #(Reg #(EventsCore)) hpm_core_events <- mkDRegOR (2, unpack (0));
`endif // `endif
// ================================================================ // ================================================================
@@ -298,7 +298,7 @@ module mkCore#(CoreId coreId)(Core);
SpecTagManager specTagManager <- mkSpecTagManager; SpecTagManager specTagManager <- mkSpecTagManager;
ReorderBufferSynth rob <- mkReorderBufferSynth; ReorderBufferSynth rob <- mkReorderBufferSynth;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
Vector#(SupSize, Bag#(BagSz, CapMem, CapMem)) bags; Vector#(SupSize, Bag#(BagSz, CapMem, CapMem)) bags;
for(Integer i = 0; i < valueof(SupSize); i=i+1) begin for(Integer i = 0; i < valueof(SupSize); i=i+1) begin
@@ -309,7 +309,7 @@ module mkCore#(CoreId coreId)(Core);
returnBags[i] <- mkSmallBag; returnBags[i] <- mkSmallBag;
end end
`endif `endif
`endif // `endif
// We have two scoreboards: one conservative and other aggressive // We have two scoreboards: one conservative and other aggressive
// - Aggressive sb is checked at rename stage, so inst after rename may be issued early // - Aggressive sb is checked at rename stage, so inst after rename may be issued early
@@ -437,7 +437,7 @@ module mkCore#(CoreId coreId)(Core);
method Bool pauseExecute = globalSpecUpdate.pendingIncorrectSpec; method Bool pauseExecute = globalSpecUpdate.pendingIncorrectSpec;
method correctSpec = globalSpecUpdate.correctSpec[finishAluCorrectSpecPort(i)].put; method correctSpec = globalSpecUpdate.correctSpec[finishAluCorrectSpecPort(i)].put;
method doStats = doStatsReg._read; method doStats = doStatsReg._read;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
method Bool checkTarget(CapMem ppc); method Bool checkTarget(CapMem ppc);
Bool ret = False; Bool ret = False;
@@ -454,7 +454,7 @@ module mkCore#(CoreId coreId)(Core);
return ret; return ret;
endmethod endmethod
`endif `endif
`endif // `endif
endinterface); endinterface);
aluExe[i] <- mkAluExePipeline(aluExeInput); aluExe[i] <- mkAluExePipeline(aluExeInput);
// truly call fetch method to train branch predictor // truly call fetch method to train branch predictor
@@ -512,12 +512,12 @@ module mkCore#(CoreId coreId)(Core);
method setRegReadyAggr_forward = writeAggr(forwardWrAggrPort); method setRegReadyAggr_forward = writeAggr(forwardWrAggrPort);
method writeRegFile = writeCons(memWrConsPort); method writeRegFile = writeCons(memWrConsPort);
method doStats = doStatsReg._read; method doStats = doStatsReg._read;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
method rob_getPredPC = rob.getOrigPredPC[valueof(AluExeNum)].get; // last getOrigPredPC port method rob_getPredPC = rob.getOrigPredPC[valueof(AluExeNum)].get; // last getOrigPredPC port
method rob_getOrig_Inst = rob.getOrig_Inst[valueof(AluExeNum)].get; // last getOrig_Inst port method rob_getOrig_Inst = rob.getOrig_Inst[valueof(AluExeNum)].get; // last getOrig_Inst port
`endif `endif
`endif // `endif
endinterface); endinterface);
let memExe <- mkMemExePipeline(memExeInput); let memExe <- mkMemExePipeline(memExeInput);
@@ -580,7 +580,7 @@ module mkCore#(CoreId coreId)(Core);
// performance counters // performance counters
Reg#(Bool) doStats = coreFix.doStatsIfc; // whether data is collected Reg#(Bool) doStats = coreFix.doStatsIfc; // whether data is collected
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// OOO execute stag (in AluExePipeline and MemExePipeline) // OOO execute stag (in AluExePipeline and MemExePipeline)
// commit stage (many in CommitStage.bsv) // commit stage (many in CommitStage.bsv)
@@ -608,7 +608,7 @@ module mkCore#(CoreId coreId)(Core);
// FIFO of perf resp // FIFO of perf resp
FIFO#(ProcPerfResp) perfRespQ <- mkFIFO1; FIFO#(ProcPerfResp) perfRespQ <- mkFIFO1;
`endif // `endif
// FIFO of perf req // FIFO of perf req
FIFO#(ProcPerfReq) perfReqQ <- mkFIFO1; FIFO#(ProcPerfReq) perfReqQ <- mkFIFO1;
@@ -721,7 +721,7 @@ module mkCore#(CoreId coreId)(Core);
`endif `endif
endmethod endmethod
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
method Action updateTargets(Vector#(SupSize, Maybe#(CapMem)) targets); method Action updateTargets(Vector#(SupSize, Maybe#(CapMem)) targets);
for(Integer i = 0; i < valueof(SupSize); i=i+1) begin for(Integer i = 0; i < valueof(SupSize); i=i+1) begin
@@ -739,7 +739,7 @@ module mkCore#(CoreId coreId)(Core);
end end
endmethod endmethod
`endif `endif
`endif // `endif
`ifdef INCLUDE_TANDEM_VERIF `ifdef INCLUDE_TANDEM_VERIF
interface v_to_TV = map (toPut, v_f_to_TV); interface v_to_TV = map (toPut, v_f_to_TV);
@@ -842,7 +842,7 @@ module mkCore#(CoreId coreId)(Core);
fetchStage.flush_predictors; fetchStage.flush_predictors;
// $display ("%0d: %m.rule flushBrPred", cur_cycle); // $display ("%0d: %m.rule flushBrPred", cur_cycle);
endrule endrule
`endif // `endif
`ifdef SELF_INV_CACHE `ifdef SELF_INV_CACHE
// Use wires to capture flush regs and empty signals. This is ok because // Use wires to capture flush regs and empty signals. This is ok because
@@ -914,7 +914,7 @@ module mkCore#(CoreId coreId)(Core);
endrule endrule
`endif `endif
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// incr cycle count // incr cycle count
(* fire_when_enabled, no_implicit_conditions *) (* fire_when_enabled, no_implicit_conditions *)
rule incCycleCnt(doStats); rule incCycleCnt(doStats);
@@ -1170,9 +1170,9 @@ module mkCore#(CoreId coreId)(Core);
perfRespQ.enq(r); perfRespQ.enq(r);
end end
endrule endrule
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
// ================================================================ // ================================================================
// Performance counters // Performance counters
// Each cache and TLB pair uses the same struct (EventsCache), but the cache accesses // Each cache and TLB pair uses the same struct (EventsCache), but the cache accesses
@@ -1220,7 +1220,7 @@ module mkCore#(CoreId coreId)(Core);
rule rl_send_perf_evts; rule rl_send_perf_evts;
csrf.send_performance_events (events); csrf.send_performance_events (events);
endrule endrule
`endif // `endif
`ifdef INCLUDE_GDB_CONTROL `ifdef INCLUDE_GDB_CONTROL
// ================================================================ // ================================================================
@@ -1531,18 +1531,18 @@ module mkCore#(CoreId coreId)(Core);
interface CoreIndInv coreIndInv; interface CoreIndInv coreIndInv;
method ActionValue#(ProcPerfResp) perfResp; method ActionValue#(ProcPerfResp) perfResp;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
perfRespQ.deq; perfRespQ.deq;
return perfRespQ.first; return perfRespQ.first;
`else // `else
perfReqQ.deq; // perfReqQ.deq;
let r = perfReqQ.first; // let r = perfReqQ.first;
return ProcPerfResp { // return ProcPerfResp {
loc: r.loc, // loc: r.loc,
pType: r.pType, // pType: r.pType,
data: 0 // data: 0
}; // };
`endif // `endif
endmethod endmethod
method terminate = csrf.terminate; method terminate = csrf.terminate;
@@ -1602,9 +1602,9 @@ module mkCore#(CoreId coreId)(Core);
interface v_to_TV = map (toGet, v_f_to_TV); interface v_to_TV = map (toGet, v_f_to_TV);
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method events_llc = events_llc_reg._write; method events_llc = events_llc_reg._write;
method events_tgc = events_tgc_reg._write; method events_tgc = events_tgc_reg._write;
`endif // `endif
endmodule endmodule

View File

@@ -58,10 +58,10 @@ import ISA_Decls_CHERI::*;
import Cur_Cycle :: *; import Cur_Cycle :: *;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import PerformanceMonitor :: *; import PerformanceMonitor :: *;
import StatCounters::*; import StatCounters::*;
`endif // `endif
// ================================================================ // ================================================================
// Project imports from Toooba // Project imports from Toooba
@@ -184,10 +184,10 @@ interface CsrFile;
method Action dcsr_cause_write (Bit #(3) dcsr_cause); method Action dcsr_cause_write (Bit #(3) dcsr_cause);
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
(* always_ready, always_enabled *) (* always_ready, always_enabled *)
method Action send_performance_events (Vector #(No_Of_Evts, Bit #(Report_Width)) evts); method Action send_performance_events (Vector #(No_Of_Evts, Bit #(Report_Width)) evts);
`endif // `endif
endinterface endinterface
// Fancy Reg functions // Fancy Reg functions
@@ -242,7 +242,7 @@ function Reg#(t) addWriteSideEffect(Reg#(t) r, Action a);
endinterface); endinterface);
endfunction endfunction
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
interface PerfCountersVec; interface PerfCountersVec;
interface Vector#(No_Of_Ctrs, Reg#(Data)) counter_vec; interface Vector#(No_Of_Ctrs, Reg#(Data)) counter_vec;
interface Vector#(No_Of_Ctrs, Reg#(Data)) event_vec; interface Vector#(No_Of_Ctrs, Reg#(Data)) event_vec;
@@ -289,7 +289,7 @@ module mkPerfCountersToooba (PerfCountersVec);
endinterface; endinterface;
method send_performance_events = perf_counters.send_performance_events; method send_performance_events = perf_counters.send_performance_events;
endmodule endmodule
`endif // `endif
function Bool has_csr_permission(CSR csr, Bit#(2) prv, Bool write); function Bool has_csr_permission(CSR csr, Bit#(2) prv, Bool write);
Bit#(12) csr_index = pack(csr); Bit#(12) csr_index = pack(csr);
@@ -754,7 +754,7 @@ module mkCsrFile #(Data hartid)(CsrFile);
Reg #(Data) rg_dscratch1 <- mkConfigRegU; Reg #(Data) rg_dscratch1 <- mkConfigRegU;
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
PerfCountersVec perf_counters <- mkPerfCountersToooba; PerfCountersVec perf_counters <- mkPerfCountersToooba;
//Reg #(Bit #(2)) rg_ctr_inhib_lsb <- mkReg (0); //Reg #(Bit #(2)) rg_ctr_inhib_lsb <- mkReg (0);
@@ -762,7 +762,7 @@ module mkCsrFile #(Data hartid)(CsrFile);
//Bit #(3) ctr_inhibit_lsb = { rg_ctr_inhib_lsb [1], 0, rg_ctr_inhib_lsb [0] }; //Bit #(3) ctr_inhibit_lsb = { rg_ctr_inhib_lsb [1], 0, rg_ctr_inhib_lsb [0] };
//Word ctr_inhibit = zeroExtend ({ perf_counters.read_ctr_inhibit, ctr_inhibit_lsb }); //Word ctr_inhibit = zeroExtend ({ perf_counters.read_ctr_inhibit, ctr_inhibit_lsb });
//CSR_Addr no_of_ctrs = fromInteger (valueOf (No_Of_Ctrs)); //CSR_Addr no_of_ctrs = fromInteger (valueOf (No_Of_Ctrs));
`endif // `endif
`ifdef SECURITY `ifdef SECURITY
// sanctum machine CSRs // sanctum machine CSRs
@@ -832,25 +832,25 @@ module mkCsrFile #(Data hartid)(CsrFile);
Reg#(CapReg) mScratchC_reg <- mkCsrReg(nullCap); Reg#(CapReg) mScratchC_reg <- mkCsrReg(nullCap);
Ehr#(2, CapReg) mepcc_reg <- mkConfigEhr(defaultValue); Ehr#(2, CapReg) mepcc_reg <- mkConfigEhr(defaultValue);
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
// Performance monitoring // Performance monitoring
Reg#(Bit#(1)) mcountinhibit_cy_reg <- mkCsrReg(0); Reg#(Bit#(1)) mcountinhibit_cy_reg <- mkCsrReg(0);
Reg#(Bit#(1)) mcountinhibit_ir_reg <- mkCsrReg(0); Reg#(Bit#(1)) mcountinhibit_ir_reg <- mkCsrReg(0);
Reg#(Data) mcountinhibit_reg = concatReg5(readOnlyReg(32'h00000000), perf_counters.inhibit, mcountinhibit_ir_reg, readOnlyReg(1'b0), mcountinhibit_cy_reg); Reg#(Data) mcountinhibit_reg = concatReg5(readOnlyReg(32'h00000000), perf_counters.inhibit, mcountinhibit_ir_reg, readOnlyReg(1'b0), mcountinhibit_cy_reg);
`endif // `endif
rule incCycle; rule incCycle;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
if(!unpack(mcountinhibit_cy_reg)) mcycle_ehr[1] <= mcycle_ehr[1] + 1; if(!unpack(mcountinhibit_cy_reg)) mcycle_ehr[1] <= mcycle_ehr[1] + 1;
`else // `else
mcycle_ehr[1] <= mcycle_ehr[1] + 1; // mcycle_ehr[1] <= mcycle_ehr[1] + 1;
`endif // `endif
endrule endrule
// Function for getting a csr given an index // Function for getting a csr given an index
function Reg#(Data) get_csr(CSR csr); function Reg#(Data) get_csr(CSR csr);
Reg#(Data) ret = readOnlyReg(64'b0); Reg#(Data) ret = readOnlyReg(64'b0);
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
let c = csr.addr; let c = csr.addr;
if ((csrAddrMHPMCOUNTER3.addr <= c) && (c <= csrAddrMHPMCOUNTER31.addr)) if ((csrAddrMHPMCOUNTER3.addr <= c) && (c <= csrAddrMHPMCOUNTER31.addr))
ret = perf_counters.counter_vec[c-csrAddrMHPMCOUNTER3.addr]; ret = perf_counters.counter_vec[c-csrAddrMHPMCOUNTER3.addr];
@@ -858,7 +858,7 @@ module mkCsrFile #(Data hartid)(CsrFile);
ret = perf_counters.event_vec[c - csrAddrMHPMEVENT3.addr]; ret = perf_counters.event_vec[c - csrAddrMHPMEVENT3.addr];
if ((csrAddrHPMCOUNTER3.addr <= c) && (c <= csrAddrHPMCOUNTER31.addr)) if ((csrAddrHPMCOUNTER3.addr <= c) && (c <= csrAddrHPMCOUNTER31.addr))
ret = perf_counters.counter_vec[c-csrAddrHPMCOUNTER3.addr]; ret = perf_counters.counter_vec[c-csrAddrHPMCOUNTER3.addr];
`endif // `endif
return (case (csr) return (case (csr)
// User CSRs // User CSRs
csrAddrFFLAGS: fflags_csr; csrAddrFFLAGS: fflags_csr;
@@ -901,10 +901,10 @@ module mkCsrFile #(Data hartid)(CsrFile);
csrAddrMIMPID: mimpid_csr; csrAddrMIMPID: mimpid_csr;
csrAddrMHARTID: mhartid_csr; csrAddrMHARTID: mhartid_csr;
csrAddrMCCSR: mccsr_csr; csrAddrMCCSR: mccsr_csr;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
//csrAddrMCOUNTERINHIBIT: perf_counters.inhibit; //csrAddrMCOUNTERINHIBIT: perf_counters.inhibit;
csrAddrMCOUNTERINHIBIT: mcountinhibit_reg; csrAddrMCOUNTERINHIBIT: mcountinhibit_reg;
`endif // `endif
`ifdef SECURITY `ifdef SECURITY
csrAddrMEVBASE: mevbase_csr; csrAddrMEVBASE: mevbase_csr;
csrAddrMEVMASK: mevmask_csr; csrAddrMEVMASK: mevmask_csr;
@@ -1396,11 +1396,11 @@ module mkCsrFile #(Data hartid)(CsrFile);
}; };
method Action incInstret(SupCnt x); method Action incInstret(SupCnt x);
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
if(!unpack(mcountinhibit_ir_reg)) minstret_ehr[1] <= minstret_ehr[1] + zeroExtend(x); if(!unpack(mcountinhibit_ir_reg)) minstret_ehr[1] <= minstret_ehr[1] + zeroExtend(x);
`else // `else
minstret_ehr[1] <= minstret_ehr[1] + zeroExtend(x); // minstret_ehr[1] <= minstret_ehr[1] + zeroExtend(x);
`endif // `endif
endmethod endmethod
method Action setTime(Data t); method Action setTime(Data t);
@@ -1473,7 +1473,7 @@ module mkCsrFile #(Data hartid)(CsrFile);
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method send_performance_events = perf_counters.send_performance_events; method send_performance_events = perf_counters.send_performance_events;
`endif // `endif
endmodule endmodule

View File

@@ -79,9 +79,9 @@ import MMIOAddrs::*;
import MMIOCore::*; import MMIOCore::*;
import DramCommon::*; import DramCommon::*;
import Performance::*; import Performance::*;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import StatCounters::*; import StatCounters::*;
`endif // `endif
// ---------------- // ----------------
// From Tooba // From Tooba
@@ -180,7 +180,7 @@ module mkProc (Proc_IFC);
statReqs.deq; statReqs.deq;
endrule endrule
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
Reg#(EventsTGC) events_tgc_reg <- mkRegU; Reg#(EventsTGC) events_tgc_reg <- mkRegU;
rule broadcastPerfEvents; rule broadcastPerfEvents;
for(Integer j = 0; j < valueof(CoreNum); j = j+1) begin for(Integer j = 0; j < valueof(CoreNum); j = j+1) begin
@@ -188,7 +188,7 @@ module mkProc (Proc_IFC);
core[j].events_tgc(events_tgc_reg); core[j].events_tgc(events_tgc_reg);
end end
endrule endrule
`endif // `endif
// ================================================================ // ================================================================
// Stub out deadlock and renameDebug interfaces // Stub out deadlock and renameDebug interfaces
@@ -361,9 +361,9 @@ module mkProc (Proc_IFC);
interface v_to_TV = core [0].v_to_TV; interface v_to_TV = core [0].v_to_TV;
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method events_tgc = events_tgc_reg._write; method events_tgc = events_tgc_reg._write;
`endif // `endif
endmodule: mkProc endmodule: mkProc

View File

@@ -43,9 +43,9 @@ import Fabric_Defs :: *;
import SoC_Map :: *; import SoC_Map :: *;
import CCTypes :: *; import CCTypes :: *;
import ProcTypes :: *; import ProcTypes :: *;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import StatCounters::*; import StatCounters::*;
`endif // `endif
`ifdef INCLUDE_GDB_CONTROL `ifdef INCLUDE_GDB_CONTROL
import DM_CPU_Req_Rsp :: *; import DM_CPU_Req_Rsp :: *;
@@ -140,9 +140,9 @@ interface Proc_IFC;
interface Vector #(SupSize, Get #(Trace_Data2)) v_to_TV; interface Vector #(SupSize, Get #(Trace_Data2)) v_to_TV;
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method Action events_tgc(EventsTGC events); method Action events_tgc(EventsTGC events);
`endif // `endif
endinterface endinterface

View File

@@ -78,9 +78,9 @@ import CacheCore :: *;
// ---------------- // ----------------
// From RISCY-ooo // From RISCY-ooo
import ProcTypes :: *; import ProcTypes :: *;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import StatCounters::*; import StatCounters::*;
`endif // `endif
// ---------------- // ----------------
// From Toooba // From Toooba
@@ -241,7 +241,7 @@ module mkCoreW_reset #(Reset porReset)
mkConnection (tagController.master, tag_controller_deburster.slave, reset_by all_harts_reset); mkConnection (tagController.master, tag_controller_deburster.slave, reset_by all_harts_reset);
*/ */
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
rule report_tagController_events; rule report_tagController_events;
EventsCacheCore cache_core_evts = tagController.events; EventsCacheCore cache_core_evts = tagController.events;
EventsTGC evts = unpack(0); EventsTGC evts = unpack(0);
@@ -256,7 +256,7 @@ module mkCoreW_reset #(Reset porReset)
`endif `endif
proc.events_tgc(evts); proc.events_tgc(evts);
endrule endrule
`endif // `endif
// PLIC (Platform-Level Interrupt Controller) // PLIC (Platform-Level Interrupt Controller)
PLIC_IFC_16_CoreNumX2_7 plic <- mkPLIC_16_CoreNumX2_7 (reset_by all_harts_reset); PLIC_IFC_16_CoreNumX2_7 plic <- mkPLIC_16_CoreNumX2_7 (reset_by all_harts_reset);

View File

@@ -60,11 +60,11 @@ import Performance::*;
import LatencyTimer::*; import LatencyTimer::*;
import RandomReplace::*; import RandomReplace::*;
import Prefetcher::*; import Prefetcher::*;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*; import PerformanceMonitor::*;
import BlueUtils::*; import BlueUtils::*;
import StatCounters::*; import StatCounters::*;
`endif // `endif
export ICRqStuck(..); export ICRqStuck(..);
export IPRqStuck(..); export IPRqStuck(..);
@@ -105,9 +105,9 @@ interface IBank#(
// performance // performance
method Action setPerfStatus(Bool stats); method Action setPerfStatus(Bool stats);
method Data getPerfData(L1IPerfType t); method Data getPerfData(L1IPerfType t);
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsL1I events; method EventsL1I events;
`endif // `endif
endinterface endinterface
module mkIBank#( module mkIBank#(
@@ -199,27 +199,27 @@ module mkIBank#(
LatencyTimer#(cRqNum, 10) latTimer <- mkLatencyTimer; LatencyTimer#(cRqNum, 10) latTimer <- mkLatencyTimer;
Count#(Bit#(32)) addedCRqs <- mkCount(0); Count#(Bit#(32)) addedCRqs <- mkCount(0);
Count#(Bit#(32)) removedCRqs <- mkCount(0); Count#(Bit#(32)) removedCRqs <- mkCount(0);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
Reg#(Bool) doStats <- mkConfigReg(True); Reg#(Bool) doStats <- mkConfigReg(True);
Count#(Data) ldCnt <- mkCount(0); Count#(Data) ldCnt <- mkCount(0);
Count#(Data) ldMissCnt <- mkCount(0); Count#(Data) ldMissCnt <- mkCount(0);
Count#(Data) ldMissLat <- mkCount(0); Count#(Data) ldMissLat <- mkCount(0);
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
Array #(Reg #(EventsL1I)) perf_events <- mkDRegOR (2, unpack (0)); Array #(Reg #(EventsL1I)) perf_events <- mkDRegOR (2, unpack (0));
`endif // `endif
function Action incrReqCnt; function Action incrReqCnt;
action action
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
ldCnt.incr(1); ldCnt.incr(1);
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsL1I events = unpack (0); EventsL1I events = unpack (0);
events.evt_LD = 1; events.evt_LD = 1;
perf_events[0] <= events; perf_events[0] <= events;
`endif // `endif
noAction; noAction;
endaction endaction
endfunction endfunction
@@ -227,18 +227,18 @@ module mkIBank#(
function Action incrMissCnt(cRqIdxT idx); function Action incrMissCnt(cRqIdxT idx);
action action
let lat <- latTimer.done(idx); let lat <- latTimer.done(idx);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
ldMissLat.incr(zeroExtend(lat)); ldMissLat.incr(zeroExtend(lat));
ldMissCnt.incr(1); ldMissCnt.incr(1);
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsL1I events = unpack (0); EventsL1I events = unpack (0);
events.evt_LD_MISS_LAT = saturating_truncate(lat); events.evt_LD_MISS_LAT = saturating_truncate(lat);
events.evt_LD_MISS = 1; events.evt_LD_MISS = 1;
perf_events[1] <= events; perf_events[1] <= events;
`endif // `endif
noAction; noAction;
endaction endaction
endfunction endfunction
@@ -906,26 +906,26 @@ module mkIBank#(
`endif `endif
method Action setPerfStatus(Bool stats); method Action setPerfStatus(Bool stats);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
doStats <= stats; doStats <= stats;
`else // `else
noAction; // noAction;
`endif // `endif
endmethod endmethod
method Data getPerfData(L1IPerfType t); method Data getPerfData(L1IPerfType t);
return (case(t) return (case(t)
`ifdef PERF_COUNT // `ifdef PERF_COUNT
L1ILdCnt: ldCnt; L1ILdCnt: ldCnt;
L1ILdMissCnt: ldMissCnt; L1ILdMissCnt: ldMissCnt;
L1ILdMissLat: ldMissLat; L1ILdMissLat: ldMissLat;
`endif // `endif
default: 0; default: 0;
endcase); endcase);
endmethod endmethod
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsL1I events = perf_events[0]; method EventsL1I events = perf_events[0];
`endif // `endif
endmodule endmodule

View File

@@ -63,11 +63,11 @@ import Performance::*;
import LatencyTimer::*; import LatencyTimer::*;
import RandomReplace::*; import RandomReplace::*;
import Prefetcher::*; import Prefetcher::*;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*; import PerformanceMonitor::*;
import StatCounters::*; import StatCounters::*;
import BlueUtils::*; import BlueUtils::*;
`endif // `endif
export L1CRqStuck(..); export L1CRqStuck(..);
export L1PRqStuck(..); export L1PRqStuck(..);
@@ -111,9 +111,9 @@ interface L1Bank#(
// performance // performance
method Action setPerfStatus(Bool stats); method Action setPerfStatus(Bool stats);
method Data getPerfData(L1DPerfType t); method Data getPerfData(L1DPerfType t);
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsL1D events; method EventsL1D events;
`endif // `endif
endinterface endinterface
typedef struct { typedef struct {
@@ -207,7 +207,7 @@ module mkL1Bank#(
// performance // performance
LatencyTimer#(cRqNum, 10) latTimer <- mkLatencyTimer; // max 1K cycle latency LatencyTimer#(cRqNum, 10) latTimer <- mkLatencyTimer; // max 1K cycle latency
`ifdef PERF_COUNT // `ifdef PERF_COUNT
Reg#(Bool) doStats <- mkConfigReg(False); Reg#(Bool) doStats <- mkConfigReg(False);
Count#(Data) ldCnt <- mkCount(0); Count#(Data) ldCnt <- mkCount(0);
Count#(Data) stCnt <- mkCount(0); Count#(Data) stCnt <- mkCount(0);
@@ -218,13 +218,13 @@ module mkL1Bank#(
Count#(Data) ldMissLat <- mkCount(0); Count#(Data) ldMissLat <- mkCount(0);
Count#(Data) stMissLat <- mkCount(0); Count#(Data) stMissLat <- mkCount(0);
Count#(Data) amoMissLat <- mkCount(0); Count#(Data) amoMissLat <- mkCount(0);
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
Array #(Reg #(EventsL1D)) perf_events <- mkDRegOR (2, unpack (0)); Array #(Reg #(EventsL1D)) perf_events <- mkDRegOR (2, unpack (0));
`endif // `endif
function Action incrReqCnt(MemOp op); function Action incrReqCnt(MemOp op);
action action
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
case(op) case(op)
Ld: ldCnt.incr(1); Ld: ldCnt.incr(1);
@@ -232,8 +232,8 @@ action
Lr, Sc, Amo: amoCnt.incr(1); Lr, Sc, Amo: amoCnt.incr(1);
endcase endcase
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsL1D events = unpack (0); EventsL1D events = unpack (0);
case(op) case(op)
Ld: events.evt_LD = 1; Ld: events.evt_LD = 1;
@@ -241,7 +241,7 @@ action
Lr, Sc, Amo: events.evt_AMO = 1; Lr, Sc, Amo: events.evt_AMO = 1;
endcase endcase
perf_events[0] <= events; perf_events[0] <= events;
`endif // `endif
noAction; noAction;
endaction endaction
endfunction endfunction
@@ -249,7 +249,7 @@ endfunction
function Action incrMissCnt(MemOp op, cRqIdxT idx); function Action incrMissCnt(MemOp op, cRqIdxT idx);
action action
let lat <- latTimer.done(idx); let lat <- latTimer.done(idx);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
case(op) case(op)
Ld: begin Ld: begin
@@ -266,8 +266,8 @@ action
end end
endcase endcase
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsL1D events = unpack (0); EventsL1D events = unpack (0);
case(op) case(op)
Ld: begin Ld: begin
@@ -284,7 +284,7 @@ action
end end
endcase endcase
perf_events[1] <= events; perf_events[1] <= events;
`endif // `endif
noAction; noAction;
endaction endaction
endfunction endfunction
@@ -1233,16 +1233,16 @@ endfunction
`endif `endif
method Action setPerfStatus(Bool stats); method Action setPerfStatus(Bool stats);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
doStats <= stats; doStats <= stats;
`else // `else
noAction; // noAction;
`endif // `endif
endmethod endmethod
method Data getPerfData(L1DPerfType t); method Data getPerfData(L1DPerfType t);
return (case(t) return (case(t)
`ifdef PERF_COUNT // `ifdef PERF_COUNT
L1DLdCnt: ldCnt; L1DLdCnt: ldCnt;
L1DStCnt: stCnt; L1DStCnt: stCnt;
L1DAmoCnt: amoCnt; L1DAmoCnt: amoCnt;
@@ -1252,13 +1252,13 @@ endfunction
L1DLdMissLat: ldMissLat; L1DLdMissLat: ldMissLat;
L1DStMissLat: stMissLat; L1DStMissLat: stMissLat;
L1DAmoMissLat: amoMissLat; L1DAmoMissLat: amoMissLat;
`endif // `endif
default: 0; default: 0;
endcase); endcase);
endmethod endmethod
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsL1D events = perf_events[0]; method EventsL1D events = perf_events[0];
`endif // `endif
endmodule endmodule
@@ -1495,7 +1495,7 @@ module mkL1Cache#(
end end
return fold(\+ , d); return fold(\+ , d);
endmethod endmethod
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsL1D events; method EventsL1D events;
EventsL1D ret = unpack(0); EventsL1D ret = unpack(0);
for(Integer i = 0; i < valueof(bankNum); i = i+1) begin for(Integer i = 0; i < valueof(bankNum); i = i+1) begin
@@ -1503,5 +1503,5 @@ module mkL1Cache#(
end end
return ret; return ret;
endmethod endmethod
`endif // `endif
endmodule endmodule

View File

@@ -55,11 +55,11 @@ import ConfigReg::*;
import RandomReplace::*; import RandomReplace::*;
import Prefetcher::*; import Prefetcher::*;
import ProcTypes::*; import ProcTypes::*;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*; import PerformanceMonitor::*;
import StatCounters::*; import StatCounters::*;
import BlueUtils::*; import BlueUtils::*;
`endif // `endif
export LLCRqStuck(..); export LLCRqStuck(..);
export LLBank(..); export LLBank(..);
@@ -111,9 +111,9 @@ interface LLBank#(
// performance // performance
method Action setPerfStatus(Bool stats); method Action setPerfStatus(Bool stats);
method Data getPerfData(LLCPerfType t); method Data getPerfData(LLCPerfType t);
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsLL events; method EventsLL events;
`endif // `endif
endinterface endinterface
typedef struct { typedef struct {
@@ -241,7 +241,7 @@ module mkLLBank#(
PrefetcherVector#(TDiv#(childNum, 2)) dataPrefetchers <- mkPrefetcherVector(mkLLDPrefetcher); PrefetcherVector#(TDiv#(childNum, 2)) dataPrefetchers <- mkPrefetcherVector(mkLLDPrefetcher);
PrefetcherVector#(TDiv#(childNum, 2)) instrPrefetchers <- mkPrefetcherVector(mkLLIPrefetcher); PrefetcherVector#(TDiv#(childNum, 2)) instrPrefetchers <- mkPrefetcherVector(mkLLIPrefetcher);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
Reg#(Bool) doStats <- mkConfigReg(True); Reg#(Bool) doStats <- mkConfigReg(True);
Count#(Data) dmaMemLdCnt <- mkCount(0); Count#(Data) dmaMemLdCnt <- mkCount(0);
Count#(Data) dmaMemLdLat <- mkCount(0); Count#(Data) dmaMemLdLat <- mkCount(0);
@@ -257,14 +257,14 @@ module mkLLBank#(
Count#(Data) upRespDataCnt <- mkCount(0); Count#(Data) upRespDataCnt <- mkCount(0);
Count#(Data) dmaLdReqCnt <- mkCount(0); Count#(Data) dmaLdReqCnt <- mkCount(0);
Count#(Data) dmaStReqCnt <- mkCount(0); Count#(Data) dmaStReqCnt <- mkCount(0);
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
Array #(Reg #(EventsLL)) perf_events <- mkDRegOR (2, unpack (0)); Array #(Reg #(EventsLL)) perf_events <- mkDRegOR (2, unpack (0));
`endif // `endif
function Action incrMissCnt(cRqIndexT idx, Bool isDma, Bool isInstructionAccess); function Action incrMissCnt(cRqIndexT idx, Bool isDma, Bool isInstructionAccess);
action action
let lat <- latTimer.done(idx); let lat <- latTimer.done(idx);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
if(isDma) begin if(isDma) begin
dmaMemLdCnt.incr(1); dmaMemLdCnt.incr(1);
@@ -279,13 +279,13 @@ action
normalMemLdLat.incr(zeroExtend(lat)); normalMemLdLat.incr(zeroExtend(lat));
end end
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsLL events = unpack (0); EventsLL events = unpack (0);
events.evt_LD_MISS_LAT = saturating_truncate(lat); // Don't support seperate DMA counts. events.evt_LD_MISS_LAT = saturating_truncate(lat); // Don't support seperate DMA counts.
events.evt_LD_MISS = 1; events.evt_LD_MISS = 1;
perf_events[1] <= events; perf_events[1] <= events;
`endif // `endif
endaction endaction
endfunction endfunction
@@ -485,7 +485,7 @@ endfunction
); );
endrule endrule
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// perf stats: insert new cRq fails because of full MSHR // perf stats: insert new cRq fails because of full MSHR
rule cRqTransfer_new_child_block( rule cRqTransfer_new_child_block(
!cRqRetryIndexQ.notEmpty && newCRqSrc == Valid (Child) && doStats !cRqRetryIndexQ.notEmpty && newCRqSrc == Valid (Child) && doStats
@@ -504,7 +504,7 @@ endfunction
mshrBlocks.incr(1); mshrBlocks.incr(1);
end end
endrule endrule
`endif // `endif
// insert new cRq from DMA to MSHR and send to pipeline // insert new cRq from DMA to MSHR and send to pipeline
rule cRqTransfer_new_dma(!cRqRetryIndexQ.notEmpty && newCRqSrc == Valid (Dma)); rule cRqTransfer_new_dma(!cRqRetryIndexQ.notEmpty && newCRqSrc == Valid (Dma));
@@ -536,7 +536,7 @@ endfunction
fshow(r), " ; ", fshow(r), " ; ",
fshow(cRq) fshow(cRq)
); );
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
if(write) begin if(write) begin
dmaStReqCnt.incr(1); dmaStReqCnt.incr(1);
@@ -545,10 +545,10 @@ endfunction
dmaLdReqCnt.incr(1); dmaLdReqCnt.incr(1);
end end
end end
`endif // `endif
endrule endrule
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// perf stats: insert new cRq fails because of full MSHR // perf stats: insert new cRq fails because of full MSHR
rule cRqTransfer_new_dma_block( rule cRqTransfer_new_dma_block(
!cRqRetryIndexQ.notEmpty && newCRqSrc == Valid (Dma) && doStats !cRqRetryIndexQ.notEmpty && newCRqSrc == Valid (Dma) && doStats
@@ -568,7 +568,7 @@ endfunction
mshrBlocks.incr(1); mshrBlocks.incr(1);
end end
endrule endrule
`endif // `endif
// send downgrade resp from child to pipeline // send downgrade resp from child to pipeline
rule cRsTransfer; rule cRsTransfer;
@@ -577,14 +577,14 @@ endfunction
pipeline.send(CRs (cRs)); pipeline.send(CRs (cRs));
if (verbose) if (verbose)
$display("%t LL %m cRsTransfer: ", $time, fshow(cRs)); $display("%t LL %m cRsTransfer: ", $time, fshow(cRs));
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
downRespCnt.incr(1); downRespCnt.incr(1);
if(isValid(cRs.data)) begin if(isValid(cRs.data)) begin
downRespDataCnt.incr(1); downRespDataCnt.incr(1);
end end
end end
`endif // `endif
endrule endrule
rule discardPrefetchRqResult(rsToCIndexQ.notEmpty && cRqIsPrefetch[rsToCIndexQ.first.cRqId]); rule discardPrefetchRqResult(rsToCIndexQ.notEmpty && cRqIsPrefetch[rsToCIndexQ.first.cRqId]);
@@ -596,14 +596,14 @@ endfunction
// mem resp for child req, will refill cache, send it to pipeline // mem resp for child req, will refill cache, send it to pipeline
(* descending_urgency = "mRsTransfer, cRsTransfer, discardPrefetchRqResult, cRqTransfer_retry, cRqTransfer_new_child, cRqTransfer_new_dma, createInstrPrefetchRq, createDataPrefetchRq" *) (* descending_urgency = "mRsTransfer, cRsTransfer, discardPrefetchRqResult, cRqTransfer_retry, cRqTransfer_new_child, cRqTransfer_new_dma, createInstrPrefetchRq, createDataPrefetchRq" *)
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// stop mshr block stats when other higher priority req is being sent to // stop mshr block stats when other higher priority req is being sent to
// pipeline // pipeline
(* preempts = "mRsTransfer, cRqTransfer_new_child_block" *) (* preempts = "mRsTransfer, cRqTransfer_new_child_block" *)
(* preempts = "mRsTransfer, cRqTransfer_new_dma_block" *) (* preempts = "mRsTransfer, cRqTransfer_new_dma_block" *)
(* preempts = "cRsTransfer, cRqTransfer_new_child_block" *) (* preempts = "cRsTransfer, cRqTransfer_new_child_block" *)
(* preempts = "cRsTransfer, cRqTransfer_new_dma_block" *) (* preempts = "cRsTransfer, cRqTransfer_new_dma_block" *)
`endif // `endif
rule mRsTransfer(rsFromMQ.first.id.refill); rule mRsTransfer(rsFromMQ.first.id.refill);
// get mem resp cRq index & data // get mem resp cRq index & data
rsFromMQ.deq; rsFromMQ.deq;
@@ -742,11 +742,11 @@ endfunction
toMQ.enq(msg); toMQ.enq(msg);
// don't deq info, do ld next time // don't deq info, do ld next time
doLdAfterReplace <= True; doLdAfterReplace <= True;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsLL events = unpack (0); EventsLL events = unpack (0);
events.evt_ST_MISS = 1; events.evt_ST_MISS = 1;
perf_events[0] <= events; perf_events[0] <= events;
`endif // `endif
if (verbose) if (verbose)
$display("%t LL %m sendToM: rep then ld: rep: ", $time, fshow(msg)); $display("%t LL %m sendToM: rep then ld: rep: ", $time, fshow(msg));
end end
@@ -832,14 +832,14 @@ endfunction
})); }));
// release MSHR entry // release MSHR entry
cRqMshr.sendRsToDmaC.releaseEntry(n); cRqMshr.sendRsToDmaC.releaseEntry(n);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
upRespCnt.incr(1); upRespCnt.incr(1);
if(isValid(rsData)) begin if(isValid(rsData)) begin
upRespDataCnt.incr(1); upRespDataCnt.incr(1);
end end
end end
`endif // `endif
endrule endrule
// send downgrade req to child // send downgrade req to child
@@ -930,11 +930,11 @@ endfunction
); );
// change round-robin // change round-robin
whichCRq <= whichCRq == fromInteger(valueOf(cRqNum) - 1) ? 0 : whichCRq + 1; whichCRq <= whichCRq == fromInteger(valueOf(cRqNum) - 1) ? 0 : whichCRq + 1;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
downReqCnt.incr(1); downReqCnt.incr(1);
end end
`endif // `endif
endrule endrule
// Final stage of pipeline: process all kinds of msg // Final stage of pipeline: process all kinds of msg
@@ -1657,16 +1657,16 @@ endfunction
endinterface endinterface
method Action setPerfStatus(Bool stats); method Action setPerfStatus(Bool stats);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
doStats <= stats; doStats <= stats;
`else // `else
noAction; // noAction;
`endif // `endif
endmethod endmethod
method Data getPerfData(LLCPerfType t); method Data getPerfData(LLCPerfType t);
return (case(t) return (case(t)
`ifdef PERF_COUNT // `ifdef PERF_COUNT
LLCDmaMemLdCnt: dmaMemLdCnt; LLCDmaMemLdCnt: dmaMemLdCnt;
LLCDmaMemLdLat: dmaMemLdLat; LLCDmaMemLdLat: dmaMemLdLat;
LLCNormalMemLdCnt: normalMemLdCnt; LLCNormalMemLdCnt: normalMemLdCnt;
@@ -1681,13 +1681,13 @@ endfunction
LLCUpRespDataCnt: upRespDataCnt; LLCUpRespDataCnt: upRespDataCnt;
LLCDmaLdReqCnt: dmaLdReqCnt; LLCDmaLdReqCnt: dmaLdReqCnt;
LLCDmaStReqCnt: dmaStReqCnt; LLCDmaStReqCnt: dmaStReqCnt;
`endif // `endif
default: 0; default: 0;
endcase); endcase);
endmethod endmethod
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsLL events = perf_events[0]; method EventsLL events = perf_events[0];
`endif // `endif
endmodule endmodule
// Scheduling notes // Scheduling notes

View File

@@ -160,7 +160,7 @@ module mkSelfInvIBank#(
Fifo#(1, DebugICacheResp) cRqDoneQ <- mkBypassFifo; Fifo#(1, DebugICacheResp) cRqDoneQ <- mkBypassFifo;
`endif `endif
`ifdef PERF_COUNT // `ifdef PERF_COUNT
Reg#(Bool) doStats <- mkConfigReg(False); Reg#(Bool) doStats <- mkConfigReg(False);
Count#(Data) ldCnt <- mkCount(0); Count#(Data) ldCnt <- mkCount(0);
Count#(Data) ldMissCnt <- mkCount(0); Count#(Data) ldMissCnt <- mkCount(0);
@@ -186,7 +186,7 @@ module mkSelfInvIBank#(
end end
endaction endaction
endfunction endfunction
`endif // `endif
function tagT getTag(Addr a) = truncateLSB(a); function tagT getTag(Addr a) = truncateLSB(a);
@@ -210,10 +210,10 @@ module mkSelfInvIBank#(
})); }));
// enq to indexQ for in order resp // enq to indexQ for in order resp
cRqIndexQ.enq(n); cRqIndexQ.enq(n);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter: cRq type // performance counter: cRq type
incrReqCnt; incrReqCnt;
`endif // `endif
if (verbose) if (verbose)
$display("%t I %m cRqTransfer: ", $time, $display("%t I %m cRqTransfer: ", $time,
fshow(n), " ; ", fshow(n), " ; ",
@@ -267,10 +267,10 @@ module mkSelfInvIBank#(
fshow(slot), " ; ", fshow(slot), " ; ",
fshow(cRqToP) fshow(cRqToP)
); );
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter: start miss timer // performance counter: start miss timer
latTimer.start(n); latTimer.start(n);
`endif // `endif
endrule endrule
// last stage of pipeline: process req // last stage of pipeline: process req
@@ -475,10 +475,10 @@ module mkSelfInvIBank#(
"pRs must be a hit" "pRs must be a hit"
); );
cRqHit(cOwner, procRq); cRqHit(cOwner, procRq);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter: miss cRq // performance counter: miss cRq
incrMissCnt(cOwner); incrMissCnt(cOwner);
`endif // `endif
end end
else begin else begin
doAssert(False, ("pRs owner must match some cRq")); doAssert(False, ("pRs owner must match some cRq"));
@@ -498,11 +498,11 @@ module mkSelfInvIBank#(
waitReconcileDone <= True; waitReconcileDone <= True;
if (verbose) if (verbose)
$display("%t I %m startReconcile", $time); $display("%t I %m startReconcile", $time);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
reconcileCnt.incr(1); reconcileCnt.incr(1);
end end
`endif // `endif
endrule endrule
rule completeReconcile(needReconcile && waitReconcileDone && pipeline.reconcile_done); rule completeReconcile(needReconcile && waitReconcileDone && pipeline.reconcile_done);
needReconcile <= False; needReconcile <= False;
@@ -573,21 +573,21 @@ module mkSelfInvIBank#(
endmethod endmethod
method Action setPerfStatus(Bool stats); method Action setPerfStatus(Bool stats);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
doStats <= stats; doStats <= stats;
`else // `else
noAction; // noAction;
`endif // `endif
endmethod endmethod
method Data getPerfData(L1IPerfType t); method Data getPerfData(L1IPerfType t);
return (case(t) return (case(t)
`ifdef PERF_COUNT // `ifdef PERF_COUNT
L1ILdCnt: ldCnt; L1ILdCnt: ldCnt;
L1ILdMissCnt: ldMissCnt; L1ILdMissCnt: ldMissCnt;
L1ILdMissLat: ldMissLat; L1ILdMissLat: ldMissLat;
L1IReconcileCnt: reconcileCnt; L1IReconcileCnt: reconcileCnt;
`endif // `endif
default: 0; default: 0;
endcase); endcase);
endmethod endmethod

View File

@@ -211,7 +211,7 @@ module mkSelfInvL1Bank#(
Reg#(Bool) waitReconcileDone <- mkReg(False); Reg#(Bool) waitReconcileDone <- mkReg(False);
// performance // performance
`ifdef PERF_COUNT // `ifdef PERF_COUNT
Reg#(Bool) doStats <- mkConfigReg(False); Reg#(Bool) doStats <- mkConfigReg(False);
Count#(Data) ldCnt <- mkCount(0); Count#(Data) ldCnt <- mkCount(0);
Count#(Data) stCnt <- mkCount(0); Count#(Data) stCnt <- mkCount(0);
@@ -260,7 +260,7 @@ module mkSelfInvL1Bank#(
end end
endaction endaction
endfunction endfunction
`endif // `endif
function tagT getTag(Addr a) = truncateLSB(a); function tagT getTag(Addr a) = truncateLSB(a);
@@ -296,10 +296,10 @@ module mkSelfInvL1Bank#(
addr: r.addr, addr: r.addr,
mshrIdx: n mshrIdx: n
})); }));
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter: cRq type // performance counter: cRq type
incrReqCnt(r.op); incrReqCnt(r.op);
`endif // `endif
if (verbose) if (verbose)
$display("%t L1 %m cRqTransfer_new: ", $time, $display("%t L1 %m cRqTransfer_new: ", $time,
fshow(n), " ; ", fshow(n), " ; ",
@@ -422,10 +422,10 @@ module mkSelfInvL1Bank#(
fshow(cRqToP) fshow(cRqToP)
); );
doAssert(slot.cs == I, "we always self-inv before req to parent"); doAssert(slot.cs == I, "we always self-inv before req to parent");
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter: start miss timer // performance counter: start miss timer
latTimer.start(n); latTimer.start(n);
`endif // `endif
endrule endrule
// last stage of pipeline: process req // last stage of pipeline: process req
@@ -550,11 +550,11 @@ module mkSelfInvL1Bank#(
); );
// release MSHR entry // release MSHR entry
cRqMshr.pipelineResp.releaseEntry(n); cRqMshr.pipelineResp.releaseEntry(n);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats && needSelfInv) begin if(doStats && needSelfInv) begin
selfInvCnt.incr(1); selfInvCnt.incr(1);
end end
`endif // `endif
end end
else begin else begin
processAmo <= Valid (AmoHitInfo { processAmo <= Valid (AmoHitInfo {
@@ -871,10 +871,10 @@ module mkSelfInvL1Bank#(
("pRs must be a hit") ("pRs must be a hit")
); );
cRqHit(cOwner, procRq, True); cRqHit(cOwner, procRq, True);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter: miss cRq // performance counter: miss cRq
incrMissCnt(procRq.op, cOwner); incrMissCnt(procRq.op, cOwner);
`endif // `endif
end end
else begin else begin
doAssert(False, ("pRs owner must match some cRq")); doAssert(False, ("pRs owner must match some cRq"));
@@ -966,11 +966,11 @@ module mkSelfInvL1Bank#(
waitReconcileDone <= True; waitReconcileDone <= True;
if (verbose) if (verbose)
$display("%t L1 %m startReconcile", $time); $display("%t L1 %m startReconcile", $time);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
reconcileCnt.incr(1); reconcileCnt.incr(1);
end end
`endif // `endif
endrule endrule
rule completeReconcile(needReconcile && waitReconcileDone && pipeline.reconcile_done); rule completeReconcile(needReconcile && waitReconcileDone && pipeline.reconcile_done);
needReconcile <= False; needReconcile <= False;
@@ -1021,16 +1021,16 @@ module mkSelfInvL1Bank#(
endmethod endmethod
method Action setPerfStatus(Bool stats); method Action setPerfStatus(Bool stats);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
doStats <= stats; doStats <= stats;
`else // `else
noAction; // noAction;
`endif // `endif
endmethod endmethod
method Data getPerfData(L1DPerfType t); method Data getPerfData(L1DPerfType t);
return (case(t) return (case(t)
`ifdef PERF_COUNT // `ifdef PERF_COUNT
L1DLdCnt: ldCnt; L1DLdCnt: ldCnt;
L1DStCnt: stCnt; L1DStCnt: stCnt;
L1DAmoCnt: amoCnt; L1DAmoCnt: amoCnt;
@@ -1042,7 +1042,7 @@ module mkSelfInvL1Bank#(
L1DAmoMissLat: amoMissLat; L1DAmoMissLat: amoMissLat;
L1DSelfInvCnt: selfInvCnt; L1DSelfInvCnt: selfInvCnt;
L1DReconcileCnt: reconcileCnt; L1DReconcileCnt: reconcileCnt;
`endif // `endif
default: 0; default: 0;
endcase); endcase);
endmethod endmethod

View File

@@ -213,7 +213,7 @@ module mkSelfInvLLBank#(
`endif `endif
// performance // performance
`ifdef PERF_COUNT // `ifdef PERF_COUNT
Reg#(Bool) doStats <- mkConfigReg(False); Reg#(Bool) doStats <- mkConfigReg(False);
Count#(Data) dmaMemLdCnt <- mkCount(0); Count#(Data) dmaMemLdCnt <- mkCount(0);
Count#(Data) dmaMemLdLat <- mkCount(0); Count#(Data) dmaMemLdLat <- mkCount(0);
@@ -245,7 +245,7 @@ module mkSelfInvLLBank#(
end end
endaction endaction
endfunction endfunction
`endif // `endif
function tagT getTag(Addr a) = truncateLSB(a); function tagT getTag(Addr a) = truncateLSB(a);
@@ -373,7 +373,7 @@ module mkSelfInvLLBank#(
); );
endrule endrule
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// perf stats: insert new cRq fails because of full MSHR // perf stats: insert new cRq fails because of full MSHR
rule cRqTransfer_new_child_block( rule cRqTransfer_new_child_block(
!cRqRetryIndexQ.notEmpty && newCRqSrc == Valid (Child) && doStats !cRqRetryIndexQ.notEmpty && newCRqSrc == Valid (Child) && doStats
@@ -392,7 +392,7 @@ module mkSelfInvLLBank#(
mshrBlocks.incr(1); mshrBlocks.incr(1);
end end
endrule endrule
`endif // `endif
// insert new cRq from DMA to MSHR and send to pipeline // insert new cRq from DMA to MSHR and send to pipeline
rule cRqTransfer_new_dma(!cRqRetryIndexQ.notEmpty && newCRqSrc == Valid (Dma)); rule cRqTransfer_new_dma(!cRqRetryIndexQ.notEmpty && newCRqSrc == Valid (Dma));
@@ -422,7 +422,7 @@ module mkSelfInvLLBank#(
fshow(r), " ; ", fshow(r), " ; ",
fshow(cRq) fshow(cRq)
); );
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
if(write) begin if(write) begin
dmaStReqCnt.incr(1); dmaStReqCnt.incr(1);
@@ -431,10 +431,10 @@ module mkSelfInvLLBank#(
dmaLdReqCnt.incr(1); dmaLdReqCnt.incr(1);
end end
end end
`endif // `endif
endrule endrule
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// perf stats: insert new cRq fails because of full MSHR // perf stats: insert new cRq fails because of full MSHR
rule cRqTransfer_new_dma_block( rule cRqTransfer_new_dma_block(
!cRqRetryIndexQ.notEmpty && newCRqSrc == Valid (Dma) && doStats !cRqRetryIndexQ.notEmpty && newCRqSrc == Valid (Dma) && doStats
@@ -454,7 +454,7 @@ module mkSelfInvLLBank#(
mshrBlocks.incr(1); mshrBlocks.incr(1);
end end
endrule endrule
`endif // `endif
// send downgrade resp from child to pipeline // send downgrade resp from child to pipeline
rule cRsTransfer; rule cRsTransfer;
@@ -462,26 +462,26 @@ module mkSelfInvLLBank#(
cRsFromCT cRs = rsFromCQ.first; cRsFromCT cRs = rsFromCQ.first;
pipeline.send(CRs (cRs)); pipeline.send(CRs (cRs));
$display("%t LL %m cRsTransfer: ", $time, fshow(cRs)); $display("%t LL %m cRsTransfer: ", $time, fshow(cRs));
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
downRespCnt.incr(1); downRespCnt.incr(1);
if(isValid(cRs.data)) begin if(isValid(cRs.data)) begin
downRespDataCnt.incr(1); downRespDataCnt.incr(1);
end end
end end
`endif // `endif
endrule endrule
// mem resp for child req, will refill cache, send it to pipeline // mem resp for child req, will refill cache, send it to pipeline
(* descending_urgency = "mRsTransfer, cRsTransfer, cRqTransfer_retry, cRqTransfer_new_child, cRqTransfer_new_dma" *) (* descending_urgency = "mRsTransfer, cRsTransfer, cRqTransfer_retry, cRqTransfer_new_child, cRqTransfer_new_dma" *)
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// stop mshr block stats when other higher priority req is being sent to // stop mshr block stats when other higher priority req is being sent to
// pipeline // pipeline
(* preempts = "mRsTransfer, cRqTransfer_new_child_block" *) (* preempts = "mRsTransfer, cRqTransfer_new_child_block" *)
(* preempts = "mRsTransfer, cRqTransfer_new_dma_block" *) (* preempts = "mRsTransfer, cRqTransfer_new_dma_block" *)
(* preempts = "cRsTransfer, cRqTransfer_new_child_block" *) (* preempts = "cRsTransfer, cRqTransfer_new_child_block" *)
(* preempts = "cRsTransfer, cRqTransfer_new_dma_block" *) (* preempts = "cRsTransfer, cRqTransfer_new_dma_block" *)
`endif // `endif
rule mRsTransfer(rsFromMQ.first.id.refill); rule mRsTransfer(rsFromMQ.first.id.refill);
// get mem resp cRq index & data // get mem resp cRq index & data
rsFromMQ.deq; rsFromMQ.deq;
@@ -504,10 +504,10 @@ module mkSelfInvLLBank#(
fshow(cRq), " ; ", fshow(cRq), " ; ",
fshow(cSlot), " ; " fshow(cSlot), " ; "
); );
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter: normal miss lat and cnt // performance counter: normal miss lat and cnt
incrMissCnt(n, False); incrMissCnt(n, False);
`endif // `endif
endrule endrule
// this mem resp is just for a DMA req, won't go into pipeline to refill cache // this mem resp is just for a DMA req, won't go into pipeline to refill cache
@@ -518,10 +518,10 @@ module mkSelfInvLLBank#(
// save data into cRq mshr & send to DMA resp IndexQ // save data into cRq mshr & send to DMA resp IndexQ
cRqMshr.mRsDeq.setData(mRs.id.mshrIdx, Valid (mRs.data)); cRqMshr.mRsDeq.setData(mRs.id.mshrIdx, Valid (mRs.data));
rsLdToDmaIndexQ_mRsDeq.enq(mRs.id.mshrIdx); rsLdToDmaIndexQ_mRsDeq.enq(mRs.id.mshrIdx);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter: dma miss lat and cnt // performance counter: dma miss lat and cnt
incrMissCnt(mRs.id.mshrIdx, True); incrMissCnt(mRs.id.mshrIdx, True);
`endif // `endif
endrule endrule
// send rd/wr to mem // send rd/wr to mem
@@ -558,10 +558,10 @@ module mkSelfInvLLBank#(
$display("%t LL %m sendToM: load only: ", $time, fshow(msg)); $display("%t LL %m sendToM: load only: ", $time, fshow(msg));
doAssert(!isValid(data), "cannot have data"); doAssert(!isValid(data), "cannot have data");
doAssert(!doLdAfterReplace, "doLdAfterReplace should be false"); doAssert(!doLdAfterReplace, "doLdAfterReplace should be false");
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter: start miss timer // performance counter: start miss timer
latTimer.start(n); latTimer.start(n);
`endif // `endif
`ifdef DEBUG_DMA `ifdef DEBUG_DMA
if(cRq.id matches tagged Dma .dmaId) begin if(cRq.id matches tagged Dma .dmaId) begin
dmaRdMissQ.enq(dmaId); // DMA read takes effect dmaRdMissQ.enq(dmaId); // DMA read takes effect
@@ -603,10 +603,10 @@ module mkSelfInvLLBank#(
toMInfoQ.deq; toMInfoQ.deq;
doLdAfterReplace <= False; doLdAfterReplace <= False;
$display("%t LL %m sendToM: rep then ld: ld: ", $time, fshow(msg)); $display("%t LL %m sendToM: rep then ld: ld: ", $time, fshow(msg));
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter: start miss timer // performance counter: start miss timer
latTimer.start(n); latTimer.start(n);
`endif // `endif
end end
else begin // do write back part else begin // do write back part
toMemT msg = Wb (WbMemRs { toMemT msg = Wb (WbMemRs {
@@ -698,14 +698,14 @@ module mkSelfInvLLBank#(
})); }));
// release MSHR entry // release MSHR entry
cRqMshr.sendRsToDmaC.releaseEntry(n); cRqMshr.sendRsToDmaC.releaseEntry(n);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
upRespCnt.incr(1); upRespCnt.incr(1);
if(isValid(rsData)) begin if(isValid(rsData)) begin
upRespDataCnt.incr(1); upRespDataCnt.incr(1);
end end
end end
`endif // `endif
endrule endrule
// send downgrade req to child // send downgrade req to child
@@ -787,11 +787,11 @@ module mkSelfInvLLBank#(
); );
// change round-robin // change round-robin
whichCRq <= whichCRq == fromInteger(valueOf(cRqNum) - 1) ? 0 : whichCRq + 1; whichCRq <= whichCRq == fromInteger(valueOf(cRqNum) - 1) ? 0 : whichCRq + 1;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
downReqCnt.incr(1); downReqCnt.incr(1);
end end
`endif // `endif
endrule endrule
// Final stage of pipeline: process all kinds of msg // Final stage of pipeline: process all kinds of msg
@@ -1417,16 +1417,16 @@ module mkSelfInvLLBank#(
endinterface endinterface
method Action setPerfStatus(Bool stats); method Action setPerfStatus(Bool stats);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
doStats <= stats; doStats <= stats;
`else // `else
noAction; // noAction;
`endif // `endif
endmethod endmethod
method Data getPerfData(LLCPerfType t); method Data getPerfData(LLCPerfType t);
return (case(t) return (case(t)
`ifdef PERF_COUNT // `ifdef PERF_COUNT
LLCDmaMemLdCnt: dmaMemLdCnt; LLCDmaMemLdCnt: dmaMemLdCnt;
LLCDmaMemLdLat: dmaMemLdLat; LLCDmaMemLdLat: dmaMemLdLat;
LLCNormalMemLdCnt: normalMemLdCnt; LLCNormalMemLdCnt: normalMemLdCnt;
@@ -1439,7 +1439,7 @@ module mkSelfInvLLBank#(
LLCUpRespDataCnt: upRespDataCnt; LLCUpRespDataCnt: upRespDataCnt;
LLCDmaLdReqCnt: dmaLdReqCnt; LLCDmaLdReqCnt: dmaLdReqCnt;
LLCDmaStReqCnt: dmaStReqCnt; LLCDmaStReqCnt: dmaStReqCnt;
`endif // `endif
default: 0; default: 0;
endcase); endcase);
endmethod endmethod

View File

@@ -64,11 +64,11 @@ import Bypass::*;
import CHERICap::*; import CHERICap::*;
import CHERICC_Fat::*; import CHERICC_Fat::*;
import ISA_Decls_CHERI::*; import ISA_Decls_CHERI::*;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import BlueUtils::*; import BlueUtils::*;
import StatCounters::*; import StatCounters::*;
import DReg::*; import DReg::*;
`endif // `endif
import Cur_Cycle :: *; import Cur_Cycle :: *;
@@ -220,14 +220,14 @@ interface AluExeInput;
// performance // performance
method Bool doStats; method Bool doStats;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
// check previous branch targets // check previous branch targets
method Bool checkTarget(CapMem ppc); method Bool checkTarget(CapMem ppc);
// check (previous) return targets // check (previous) return targets
method Bool checkReturnTarget(CapMem ppc); method Bool checkReturnTarget(CapMem ppc);
`endif `endif
`endif // `endif
endinterface endinterface
interface AluExePipeline; interface AluExePipeline;
@@ -237,11 +237,11 @@ interface AluExePipeline;
interface SpeculationUpdate specUpdate; interface SpeculationUpdate specUpdate;
method Data getPerf(ExeStagePerfType t); method Data getPerf(ExeStagePerfType t);
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
method EventsTransExe events; method EventsTransExe events;
`endif `endif
`endif // `endif
endinterface endinterface
module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
@@ -260,18 +260,18 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
Integer exeSendBypassPort = 0; Integer exeSendBypassPort = 0;
Integer finishSendBypassPort = 1; Integer finishSendBypassPort = 1;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
Array#(Reg#(EventsTransExe)) events_reg <- mkDRegOR(2, unpack(0)); Array#(Reg#(EventsTransExe)) events_reg <- mkDRegOR(2, unpack(0));
`endif `endif
`endif // `endif
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counters // performance counters
Count#(Data) exeRedirectBrCnt <- mkCount(0); Count#(Data) exeRedirectBrCnt <- mkCount(0);
Count#(Data) exeRedirectJrCnt <- mkCount(0); Count#(Data) exeRedirectJrCnt <- mkCount(0);
Count#(Data) exeRedirectOtherCnt <- mkCount(0); Count#(Data) exeRedirectOtherCnt <- mkCount(0);
`endif // `endif
rule doDispatchAlu; rule doDispatchAlu;
rsAlu.doDispatch; rsAlu.doDispatch;
@@ -336,7 +336,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
let ppc = inIfc.rob_getPredPC(x.tag); let ppc = inIfc.rob_getPredPC(x.tag);
let orig_inst = inIfc.rob_getOrig_Inst (x.tag); let orig_inst = inIfc.rob_getOrig_Inst (x.tag);
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
let ppc_addr = getAddr(ppc); let ppc_addr = getAddr(ppc);
let pc_addr = getAddr(pc); let pc_addr = getAddr(pc);
@@ -361,7 +361,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
end end
end end
`endif `endif
`endif // `endif
`ifdef KONATA `ifdef KONATA
$display("KONATAE\t%0d\t%0d\t0\tAlu1", cur_cycle, x.u_id); $display("KONATAE\t%0d\t%0d\t0\tAlu1", cur_cycle, x.u_id);
@@ -511,7 +511,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
$display("KONATAS\t%0d\t%0d\t0\tAlu4\t%0d", cur_cycle, x.u_id, cur_cycle); $display("KONATAS\t%0d\t%0d\t0\tAlu4\t%0d", cur_cycle, x.u_id, cur_cycle);
$fflush; $fflush;
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
// get PC and PPC // get PC and PPC
let pc = getAddr(x.controlFlow.pc); let pc = getAddr(x.controlFlow.pc);
@@ -523,7 +523,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
events_reg[0] <= events; events_reg[0] <= events;
end end
`endif `endif
`endif // `endif
let train_spec_bits = 0; let train_spec_bits = 0;
`ifdef NO_SPEC_TRAINING `ifdef NO_SPEC_TRAINING
@@ -554,7 +554,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
if (verbose) if (verbose)
$display("alu mispredict pc: %x, nextPc: %x, %d", $display("alu mispredict pc: %x, nextPc: %x, %d",
x.controlFlow.pc, x.controlFlow.nextPc, cur_cycle); x.controlFlow.pc, x.controlFlow.nextPc, cur_cycle);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter // performance counter
if(inIfc.doStats) begin if(inIfc.doStats) begin
case(x.iType) case(x.iType)
@@ -563,7 +563,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
default: exeRedirectOtherCnt.incr(1); default: exeRedirectOtherCnt.incr(1);
endcase endcase
end end
`endif // `endif
end end
else (* nosplit *) begin else (* nosplit *) begin
// release spec tag // release spec tag
@@ -603,19 +603,19 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
method Data getPerf(ExeStagePerfType t); method Data getPerf(ExeStagePerfType t);
return (case(t) return (case(t)
`ifdef PERF_COUNT // `ifdef PERF_COUNT
ExeRedirectBr: exeRedirectBrCnt; ExeRedirectBr: exeRedirectBrCnt;
ExeRedirectJr: exeRedirectJrCnt; ExeRedirectJr: exeRedirectJrCnt;
ExeRedirectOther: exeRedirectOtherCnt; ExeRedirectOther: exeRedirectOtherCnt;
`endif // `endif
default: 0; default: 0;
endcase); endcase);
endmethod endmethod
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
method events = events_reg[0]; method events = events_reg[0];
`endif `endif
`endif // `endif
endmodule endmodule

View File

@@ -66,9 +66,9 @@ import CHERICap::*;
import CHERICC_Fat::*; import CHERICC_Fat::*;
import ISA_Decls_CHERI::*; import ISA_Decls_CHERI::*;
import RegFile::*; // Just for the interface import RegFile::*; // Just for the interface
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import StatCounters::*; import StatCounters::*;
`endif // `endif
`ifdef RVFI `ifdef RVFI
import RVFI_DII_Types::*; import RVFI_DII_Types::*;
@@ -151,14 +151,14 @@ interface CommitInput;
// deadlock check // deadlock check
method Bool checkDeadlock; method Bool checkDeadlock;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
// update branch targets // update branch targets
method Action updateTargets(Vector#(SupSize, Maybe#(CapMem)) targets); method Action updateTargets(Vector#(SupSize, Maybe#(CapMem)) targets);
// update return targets // update return targets
method Action updateReturnTargets(Vector#(SupSize, Maybe#(CapMem)) returnTargets); method Action updateReturnTargets(Vector#(SupSize, Maybe#(CapMem)) returnTargets);
`endif `endif
`endif // `endif
`ifdef INCLUDE_TANDEM_VERIF `ifdef INCLUDE_TANDEM_VERIF
interface Vector #(SupSize, Put #(Trace_Data2)) v_to_TV; interface Vector #(SupSize, Put #(Trace_Data2)) v_to_TV;
@@ -197,9 +197,9 @@ interface CommitStage;
method Bool is_debug_halted; method Bool is_debug_halted;
method Action debug_resume; method Action debug_resume;
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsCore events; method EventsCore events;
`endif // `endif
endinterface endinterface
// we apply actions the end of commit rule // we apply actions the end of commit rule
@@ -422,7 +422,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
end end
// commit stage performance counters // commit stage performance counters
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// inst // inst
Count#(Data) instCnt <- mkCount(0); Count#(Data) instCnt <- mkCount(0);
Count#(Data) userInstCnt <- mkCount(0); Count#(Data) userInstCnt <- mkCount(0);
@@ -451,11 +451,11 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
Count#(Data) flushSecurityCnt <- mkCount(0); Count#(Data) flushSecurityCnt <- mkCount(0);
Count#(Data) flushBPCnt <- mkCount(0); Count#(Data) flushBPCnt <- mkCount(0);
Count#(Data) flushCacheCnt <- mkCount(0); Count#(Data) flushCacheCnt <- mkCount(0);
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
Reg#(EventsCore) events_reg <- mkDReg(unpack(0)); Reg#(EventsCore) events_reg <- mkDReg(unpack(0));
`endif // `endif
`ifdef RVFI `ifdef RVFI
// RVFI trace report. Not an input? // RVFI trace report. Not an input?
@@ -568,11 +568,11 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
if(flushTlb) begin if(flushTlb) begin
`endif `endif
inIfc.setFlushTlbs; inIfc.setFlushTlbs;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
flushTlbCnt.incr(1); flushTlbCnt.incr(1);
end end
`endif // `endif
end end
// notify TLB to keep update of CSR changes // notify TLB to keep update of CSR changes
inIfc.setUpdateVMInfo; inIfc.setUpdateVMInfo;
@@ -596,28 +596,28 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
// valid because these wrong path inst/req will not interfere with // valid because these wrong path inst/req will not interfere with
// whatever CSR changes we are making now. // whatever CSR changes we are making now.
if(flushSecurity) begin if(flushSecurity) begin
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
flushSecurityCnt.incr(1); flushSecurityCnt.incr(1);
end end
`endif // `endif
`ifndef DISABLE_SECURE_FLUSH_BP `ifndef DISABLE_SECURE_FLUSH_BP
inIfc.setFlushBrPred; inIfc.setFlushBrPred;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
flushBPCnt.incr(1); flushBPCnt.incr(1);
end end
`endif // `endif
`endif `endif
`ifndef DISABLE_SECURE_FLUSH_CACHE `ifndef DISABLE_SECURE_FLUSH_CACHE
inIfc.setFlushCaches; inIfc.setFlushCaches;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
flushCacheCnt.incr(1); flushCacheCnt.incr(1);
end end
`endif // `endif
`endif `endif
end end
@@ -734,7 +734,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
// faulting mem inst may have claimed phy reg, we should not commit it; // faulting mem inst may have claimed phy reg, we should not commit it;
// instead, we kill the renaming by calling killAll // instead, we kill the renaming by calling killAll
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter // performance counter
if(inIfc.doStats) begin if(inIfc.doStats) begin
if(trap matches tagged Exception .e) begin if(trap matches tagged Exception .e) begin
@@ -744,15 +744,15 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
interruptCnt.incr(1); interruptCnt.incr(1);
end end
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsCore events = unpack(0); EventsCore events = unpack(0);
events.evt_TRAP = 1; events.evt_TRAP = 1;
if(trap matches tagged Interrupt .i) begin if(trap matches tagged Interrupt .i) begin
events.evt_INTERRUPT = 1; events.evt_INTERRUPT = 1;
end end
events_reg <= events; events_reg <= events;
`endif // `endif
// checks // checks
doAssert(x.rob_inst_state == Executed, "must be executed"); doAssert(x.rob_inst_state == Executed, "must be executed");
doAssert(x.spec_bits == 0, "cannot have spec bits"); doAssert(x.spec_bits == 0, "cannot have spec bits");
@@ -873,7 +873,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
// the killed Ld should have claimed phy reg, we should not commit it; // the killed Ld should have claimed phy reg, we should not commit it;
// instead, we have kill the renaming by calling killAll // instead, we have kill the renaming by calling killAll
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
case(killBy) case(killBy)
Ld: comLdKillByLdCnt.incr(1); Ld: comLdKillByLdCnt.incr(1);
@@ -881,7 +881,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
Cache: comLdKillByCacheCnt.incr(1); Cache: comLdKillByCacheCnt.incr(1);
endcase endcase
end end
`endif // `endif
// checks // checks
doAssert(!x.epochIncremented, "cannot increment epoch before"); doAssert(!x.epochIncremented, "cannot increment epoch before");
@@ -1027,7 +1027,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
$fflush; $fflush;
printCommits[0][1] <= tagged Valid x.u_id; printCommits[0][1] <= tagged Valid x.u_id;
`endif `endif
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
comSysCnt.incr(1); comSysCnt.incr(1);
// inst count stats // inst count stats
@@ -1036,14 +1036,14 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
userInstCnt.incr(1); userInstCnt.incr(1);
end end
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsCore events = unpack(0); EventsCore events = unpack(0);
case(x.iType) case(x.iType)
Fence, FenceI, SFence: events.evt_FENCE = 1; Fence, FenceI, SFence: events.evt_FENCE = 1;
endcase endcase
events_reg <= events; events_reg <= events;
`endif // `endif
`ifdef CHECK_DEADLOCK `ifdef CHECK_DEADLOCK
commitInst.send; commitInst.send;
if(csrf.decodeInfo.prv == 0) begin if(csrf.decodeInfo.prv == 0) begin
@@ -1148,22 +1148,22 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
Data po_mstatus = ?; Data po_mstatus = ?;
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
// update targets vector // update targets vector
Vector#(SupSize, Maybe#(CapMem)) targets; Vector#(SupSize, Maybe#(CapMem)) targets;
// update return targets vector // update return targets vector
Vector#(SupSize, Maybe#(CapMem)) returnTargets; Vector#(SupSize, Maybe#(CapMem)) returnTargets;
`endif `endif
`endif // `endif
// compute what actions to take // compute what actions to take
for(Integer i = 0; i < valueof(SupSize); i = i+1) begin for(Integer i = 0; i < valueof(SupSize); i = i+1) begin
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
Maybe#(CapMem) tar = tagged Invalid; Maybe#(CapMem) tar = tagged Invalid;
Maybe#(CapMem) retTar = tagged Invalid; Maybe#(CapMem) retTar = tagged Invalid;
`endif `endif
`endif // `endif
if(!stop && rob.deqPort[i].canDeq) begin if(!stop && rob.deqPort[i].canDeq) begin
let x = rob.deqPort[i].deq_data; let x = rob.deqPort[i].deq_data;
let inst_tag = rob.deqPort[i].getDeqInstTag; let inst_tag = rob.deqPort[i].getDeqInstTag;
@@ -1207,7 +1207,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
// inst can be committed, deq it // inst can be committed, deq it
rob.deqPort[i].deq; rob.deqPort[i].deq;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
// return address stack link reg is x1 or x5 // return address stack link reg is x1 or x5
function Bool linkedR(Maybe#(ArchRIndx) register); function Bool linkedR(Maybe#(ArchRIndx) register);
@@ -1230,7 +1230,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
end end
end end
`endif `endif
`endif // `endif
// every inst here should have been renamed, commit renaming // every inst here should have been renamed, commit renaming
regRenamingTable.commit[i].commit; regRenamingTable.commit[i].commit;
@@ -1328,12 +1328,12 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
`endif `endif
end end
end end
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
targets[i] = tar; targets[i] = tar;
returnTargets[i] = retTar; returnTargets[i] = retTar;
`endif `endif
`endif // `endif
end end
rg_serial_num <= rg_serial_num + instret; rg_serial_num <= rg_serial_num + instret;
@@ -1359,7 +1359,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
end end
`endif `endif
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter // performance counter
if(inIfc.doStats) begin if(inIfc.doStats) begin
// branch stats // branch stats
@@ -1379,8 +1379,8 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
supComUserCnt.incr(1); supComUserCnt.incr(1);
end end
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsCore events = unpack(0); EventsCore events = unpack(0);
events.evt_BRANCH = zeroExtend(brCnt); events.evt_BRANCH = zeroExtend(brCnt);
events.evt_JAL = zeroExtend(jmpCnt); events.evt_JAL = zeroExtend(jmpCnt);
@@ -1400,7 +1400,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
inIfc.updateTargets(targets); inIfc.updateTargets(targets);
inIfc.updateReturnTargets(returnTargets); inIfc.updateReturnTargets(returnTargets);
`endif `endif
`endif // `endif
`ifdef RVFI `ifdef RVFI
rvfiQ.enq(rvfis); rvfiQ.enq(rvfis);
@@ -1446,7 +1446,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
method Data getPerf(ComStagePerfType t); method Data getPerf(ComStagePerfType t);
return (case(t) return (case(t)
`ifdef PERF_COUNT // `ifdef PERF_COUNT
InstCnt: instCnt; InstCnt: instCnt;
UserInstCnt: userInstCnt; UserInstCnt: userInstCnt;
SupComUserCnt: supComUserCnt; SupComUserCnt: supComUserCnt;
@@ -1468,7 +1468,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
FlushSecurityCnt: flushSecurityCnt; FlushSecurityCnt: flushSecurityCnt;
FlushBPCnt: flushBPCnt; FlushBPCnt: flushBPCnt;
FlushCacheCnt: flushCacheCnt; FlushCacheCnt: flushCacheCnt;
`endif // `endif
default: 0; default: 0;
endcase); endcase);
endmethod endmethod
@@ -1509,8 +1509,8 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
endmethod endmethod
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method events = events_reg; method events = events_reg;
`endif // `endif
endmodule endmodule

View File

@@ -165,9 +165,9 @@ interface FetchStage;
// performance // performance
interface Perf#(DecStagePerfType) perf; interface Perf#(DecStagePerfType) perf;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method Bool redirect_evt; method Bool redirect_evt;
`endif // `endif
endinterface endinterface
// PC "compression" types to facilitate storing common upper PC bits in a // PC "compression" types to facilitate storing common upper PC bits in a
@@ -471,7 +471,7 @@ module mkFetchStage(FetchStage);
// performance counters // performance counters
Fifo#(1, DecStagePerfType) perfReqQ <- mkCFFifo; // perf req FIFO Fifo#(1, DecStagePerfType) perfReqQ <- mkCFFifo; // perf req FIFO
`ifdef PERF_COUNT // `ifdef PERF_COUNT
Reg#(Bool) doStats <- mkConfigReg(False); Reg#(Bool) doStats <- mkConfigReg(False);
// decode stage redirect // decode stage redirect
Count#(Data) decRedirectBrCnt <- mkCount(0); Count#(Data) decRedirectBrCnt <- mkCount(0);
@@ -495,10 +495,10 @@ module mkFetchStage(FetchStage);
data: d data: d
}); });
endrule endrule
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
Reg#(Bool) redirect_evt_reg <- mkDReg(False); Reg#(Bool) redirect_evt_reg <- mkDReg(False);
`endif // `endif
`ifdef KONATA `ifdef KONATA
Reg#(Bit#(64)) uid <- mkReg(0); Reg#(Bit#(64)) uid <- mkReg(0);
Reg#(Bool) k_reset <- mkReg(True); Reg#(Bool) k_reset <- mkReg(True);
@@ -856,11 +856,11 @@ module mkFetchStage(FetchStage);
`endif `endif
Maybe#(TrainNAP) trainNAP = Invalid; // training data sent to next addr pred Maybe#(TrainNAP) trainNAP = Invalid; // training data sent to next addr pred
Bool decode_epoch_local = decode_epoch[0]; // next value for decode epoch Bool decode_epoch_local = decode_epoch[0]; // next value for decode epoch
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter: inst being redirect by decode stage // performance counter: inst being redirect by decode stage
// Note that only 1 redirection may happen in a cycle // Note that only 1 redirection may happen in a cycle
Maybe#(IType) redirectInst = Invalid; Maybe#(IType) redirectInst = Invalid;
`endif // `endif
Bool likely_epoch_change = False; Bool likely_epoch_change = False;
Maybe#(CapMem) m_push_addr = Invalid; Maybe#(CapMem) m_push_addr = Invalid;
for (Integer i = 0; i < valueof(SupSize); i=i+1) begin for (Integer i = 0; i < valueof(SupSize); i=i+1) begin
@@ -977,11 +977,11 @@ module mkFetchStage(FetchStage);
// train next addr pred when mispredict // train next addr pred when mispredict
let last_x16_pc = addPc(pc, ((in.inst_kind == Inst_32b) ? 2 : 0)); let last_x16_pc = addPc(pc, ((in.inst_kind == Inst_32b) ? 2 : 0));
trainNAP = Valid (TrainNAP {pc: last_x16_pc, nextPc: decode_pred_next_pc}); trainNAP = Valid (TrainNAP {pc: last_x16_pc, nextPc: decode_pred_next_pc});
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance stats: record decode redirect // performance stats: record decode redirect
doAssert(redirectInst == Invalid, "at most 1 decode redirect per cycle"); doAssert(redirectInst == Invalid, "at most 1 decode redirect per cycle");
redirectInst = Valid (dInst.iType); redirectInst = Valid (dInst.iType);
`endif // `endif
end end
end // if (!isValid(cause)) end // if (!isValid(cause))
if (isValid(m_push_addr)) trainInfo.ras = trainInfo.ras + 1; if (isValid(m_push_addr)) trainInfo.ras = trainInfo.ras + 1;
@@ -1049,7 +1049,7 @@ module mkFetchStage(FetchStage);
if (trainNAP matches tagged Valid .x) begin if (trainNAP matches tagged Valid .x) begin
napTrainByDecQ.enq(x); napTrainByDecQ.enq(x);
end end
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// performance counter: check whether redirect happens // performance counter: check whether redirect happens
if(redirectInst matches tagged Valid .iType &&& doStats) begin if(redirectInst matches tagged Valid .iType &&& doStats) begin
case(iType) case(iType)
@@ -1059,7 +1059,7 @@ module mkFetchStage(FetchStage);
default: decRedirectOtherCnt.incr(1); default: decRedirectOtherCnt.incr(1);
endcase endcase
end end
`endif // `endif
endrule endrule
rule reportDecodePc; rule reportDecodePc;
@@ -1143,9 +1143,9 @@ module mkFetchStage(FetchStage);
// this redirect may be caused by a trap/system inst in commit stage // this redirect may be caused by a trap/system inst in commit stage
// we conservatively set wait for flush TODO make this an input parameter // we conservatively set wait for flush TODO make this an input parameter
waitForFlush[2] <= True; waitForFlush[2] <= True;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
redirect_evt_reg <= True; redirect_evt_reg <= True;
`endif // `endif
execute_redirect_count <= execute_redirect_count + 1; execute_redirect_count <= execute_redirect_count + 1;
endmethod endmethod
@@ -1222,11 +1222,11 @@ module mkFetchStage(FetchStage);
interface Perf perf; interface Perf perf;
method Action setStatus(Bool stats); method Action setStatus(Bool stats);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
doStats <= stats; doStats <= stats;
`else // `else
noAction; // noAction;
`endif // `endif
endmethod endmethod
method Action req(DecStagePerfType r); method Action req(DecStagePerfType r);
@@ -1234,26 +1234,26 @@ module mkFetchStage(FetchStage);
endmethod endmethod
method ActionValue#(PerfResp#(DecStagePerfType)) resp; method ActionValue#(PerfResp#(DecStagePerfType)) resp;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
perfRespQ.deq; perfRespQ.deq;
return perfRespQ.first; return perfRespQ.first;
`else // `else
perfReqQ.deq; // perfReqQ.deq;
return PerfResp { // return PerfResp {
pType: perfReqQ.first, // pType: perfReqQ.first,
data: 0 // data: 0
}; // };
`endif // `endif
endmethod endmethod
`ifdef PERF_COUNT // `ifdef PERF_COUNT
method Bool respValid = perfRespQ.notEmpty; method Bool respValid = perfRespQ.notEmpty;
`else // `else
method Bool respValid = perfReqQ.notEmpty; // method Bool respValid = perfReqQ.notEmpty;
`endif // `endif
endinterface endinterface
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method Bool redirect_evt = redirect_evt_reg._read; method Bool redirect_evt = redirect_evt_reg._read;
`endif // `endif
endmodule endmodule

View File

@@ -172,13 +172,13 @@ module mkFpuMulDivExePipeline#(FpuMulDivExeInput inIfc)(FpuMulDivExePipeline);
FpuExec fpuExec <- mkFpuExecPipeline; FpuExec fpuExec <- mkFpuExecPipeline;
// fpu/mul/div performance counters // fpu/mul/div performance counters
`ifdef PERF_COUNT // `ifdef PERF_COUNT
Count#(Data) exeIntMulCnt <- mkCount(0); Count#(Data) exeIntMulCnt <- mkCount(0);
Count#(Data) exeIntDivCnt <- mkCount(0); Count#(Data) exeIntDivCnt <- mkCount(0);
Count#(Data) exeFpFmaCnt <- mkCount(0); Count#(Data) exeFpFmaCnt <- mkCount(0);
Count#(Data) exeFpDivCnt <- mkCount(0); Count#(Data) exeFpDivCnt <- mkCount(0);
Count#(Data) exeFpSqrtCnt <- mkCount(0); Count#(Data) exeFpSqrtCnt <- mkCount(0);
`endif // `endif
rule doDispatchFpuMulDiv; rule doDispatchFpuMulDiv;
rsFpuMulDiv.doDispatch; rsFpuMulDiv.doDispatch;
@@ -345,11 +345,11 @@ module mkFpuMulDivExePipeline#(FpuMulDivExeInput inIfc)(FpuMulDivExePipeline);
`else `else
doFinish(resp.dst, resp.tag, resp.res.data, resp.res.fflags); doFinish(resp.dst, resp.tag, resp.res.data, resp.res.fflags);
`endif `endif
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
exeFpFmaCnt.incr(1); exeFpFmaCnt.incr(1);
end end
`endif // `endif
endrule endrule
rule doFinishFpDiv; rule doFinishFpDiv;
@@ -360,11 +360,11 @@ module mkFpuMulDivExePipeline#(FpuMulDivExeInput inIfc)(FpuMulDivExePipeline);
`else `else
doFinish(resp.dst, resp.tag, resp.res.data, resp.res.fflags); doFinish(resp.dst, resp.tag, resp.res.data, resp.res.fflags);
`endif `endif
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
exeFpDivCnt.incr(1); exeFpDivCnt.incr(1);
end end
`endif // `endif
endrule endrule
rule doFinishFpSqrt; rule doFinishFpSqrt;
@@ -375,11 +375,11 @@ module mkFpuMulDivExePipeline#(FpuMulDivExeInput inIfc)(FpuMulDivExePipeline);
`else `else
doFinish(resp.dst, resp.tag, resp.res.data, resp.res.fflags); doFinish(resp.dst, resp.tag, resp.res.data, resp.res.fflags);
`endif `endif
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
exeFpSqrtCnt.incr(1); exeFpSqrtCnt.incr(1);
end end
`endif // `endif
endrule endrule
rule doFinishIntMul; rule doFinishIntMul;
@@ -390,11 +390,11 @@ module mkFpuMulDivExePipeline#(FpuMulDivExeInput inIfc)(FpuMulDivExePipeline);
`else `else
doFinish(resp.dst, resp.tag, resp.data, 0); doFinish(resp.dst, resp.tag, resp.data, 0);
`endif `endif
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
exeIntMulCnt.incr(1); exeIntMulCnt.incr(1);
end end
`endif // `endif
endrule endrule
rule doFinishIntDiv; rule doFinishIntDiv;
@@ -405,11 +405,11 @@ module mkFpuMulDivExePipeline#(FpuMulDivExeInput inIfc)(FpuMulDivExePipeline);
`else `else
doFinish(resp.dst, resp.tag, resp.data, 0); doFinish(resp.dst, resp.tag, resp.data, 0);
`endif `endif
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
exeIntDivCnt.incr(1); exeIntDivCnt.incr(1);
end end
`endif // `endif
endrule endrule
interface recvBypass = map(getRecvBypassDataIfc, bypassWire); interface recvBypass = map(getRecvBypassDataIfc, bypassWire);
@@ -426,13 +426,13 @@ module mkFpuMulDivExePipeline#(FpuMulDivExeInput inIfc)(FpuMulDivExePipeline);
method Data getPerf(ExeStagePerfType t); method Data getPerf(ExeStagePerfType t);
return (case(t) return (case(t)
`ifdef PERF_COUNT // `ifdef PERF_COUNT
ExeIntMulCnt: exeIntMulCnt; ExeIntMulCnt: exeIntMulCnt;
ExeIntDivCnt: exeIntDivCnt; ExeIntDivCnt: exeIntDivCnt;
ExeFpFmaCnt: exeFpFmaCnt; ExeFpFmaCnt: exeFpFmaCnt;
ExeFpDivCnt: exeFpDivCnt; ExeFpDivCnt: exeFpDivCnt;
ExeFpSqrtCnt: exeFpSqrtCnt; ExeFpSqrtCnt: exeFpSqrtCnt;
`endif // `endif
default: 0; default: 0;
endcase); endcase);
endmethod endmethod

View File

@@ -75,12 +75,12 @@ import CHERICap::*;
import CHERICC_Fat::*; import CHERICC_Fat::*;
import ISA_Decls_CHERI::*; import ISA_Decls_CHERI::*;
import CacheUtils::*; import CacheUtils::*;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*; import PerformanceMonitor::*;
import BlueUtils::*; import BlueUtils::*;
import StatCounters::*; import StatCounters::*;
import DReg::*; import DReg::*;
`endif // `endif
import Cur_Cycle :: *; import Cur_Cycle :: *;
@@ -242,12 +242,12 @@ interface MemExeInput;
// performance // performance
method Bool doStats; method Bool doStats;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
method CapMem rob_getPredPC(InstTag t); method CapMem rob_getPredPC(InstTag t);
method Bit #(32) rob_getOrig_Inst (InstTag t); method Bit #(32) rob_getOrig_Inst (InstTag t);
`endif `endif
`endif // `endif
endinterface endinterface
interface MemExePipeline; interface MemExePipeline;
@@ -263,12 +263,12 @@ interface MemExePipeline;
interface Server#(void, void) reconcile; interface Server#(void, void) reconcile;
`endif `endif
method Data getPerf(ExeStagePerfType t); method Data getPerf(ExeStagePerfType t);
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsCore events; method EventsCore events;
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
method EventsTransExe events_trans; method EventsTransExe events_trans;
`endif `endif
`endif // `endif
endinterface endinterface
module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline); module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
@@ -282,7 +282,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
// These are always included as they are used by both stat counter systems. // These are always included as they are used by both stat counter systems.
LatencyTimer#(LdQSize, 10) ldMemLatTimer <- mkLatencyTimer; LatencyTimer#(LdQSize, 10) ldMemLatTimer <- mkLatencyTimer;
LatencyTimer#(SBSize, 10) stMemLatTimer <- mkLatencyTimer; LatencyTimer#(SBSize, 10) stMemLatTimer <- mkLatencyTimer;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// load issue stall // load issue stall
Count#(Data) exeLdStallByLdCnt <- mkCount(0); Count#(Data) exeLdStallByLdCnt <- mkCount(0);
Count#(Data) exeLdStallByStCnt <- mkCount(0); Count#(Data) exeLdStallByStCnt <- mkCount(0);
@@ -306,14 +306,14 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
Count#(Data) exeFenceCnt <- mkCount(0); Count#(Data) exeFenceCnt <- mkCount(0);
Count#(Data) exeFenceAcqCnt <- mkCount(0); Count#(Data) exeFenceAcqCnt <- mkCount(0);
Count#(Data) exeFenceRelCnt <- mkCount(0); Count#(Data) exeFenceRelCnt <- mkCount(0);
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
Array #(Reg #(EventsCore)) events_reg <- mkDRegOR (5, unpack (0)); Array #(Reg #(EventsCore)) events_reg <- mkDRegOR (5, unpack (0));
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
Reg#(EventsTransExe) events_trans_reg <- mkDReg(unpack(0)); Reg#(EventsTransExe) events_trans_reg <- mkDReg(unpack(0));
`endif `endif
`endif // `endif
// reservation station // reservation station
ReservationStationMem rsMem <- mkReservationStationMem; ReservationStationMem rsMem <- mkReservationStationMem;
@@ -377,17 +377,17 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
end end
// perf: load mem latency // perf: load mem latency
let lat <- ldMemLatTimer.done(tag); let lat <- ldMemLatTimer.done(tag);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
exeLdMemLat.incr(zeroExtend(lat)); exeLdMemLat.incr(zeroExtend(lat));
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsCore events = unpack(0); EventsCore events = unpack(0);
events.evt_LOAD_WAIT = saturating_truncate(lat); events.evt_LOAD_WAIT = saturating_truncate(lat);
events.evt_MEM_CAP_LOAD_TAG_SET = (d.tag) ? 1 : 0; events.evt_MEM_CAP_LOAD_TAG_SET = (d.tag) ? 1 : 0;
events_reg[1] <= events; events_reg[1] <= events;
`endif // `endif
endmethod endmethod
method Action respLrScAmo(DProcReqId id, MemTaggedData d); method Action respLrScAmo(DProcReqId id, MemTaggedData d);
respLrScAmoQ.enq(d); respLrScAmoQ.enq(d);
@@ -405,17 +405,17 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
end end
// perf: store mem latency // perf: store mem latency
let lat <- stMemLatTimer.done(0); let lat <- stMemLatTimer.done(0);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
exeStMemLat.incr(zeroExtend(lat)); exeStMemLat.incr(zeroExtend(lat));
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsCore events = unpack(0); EventsCore events = unpack(0);
if (pack(waitSt.shiftedBE) == -1) events.evt_MEM_CAP_STORE = 1; if (pack(waitSt.shiftedBE) == -1) events.evt_MEM_CAP_STORE = 1;
events.evt_STORE_WAIT = saturating_truncate(lat); events.evt_STORE_WAIT = saturating_truncate(lat);
events_reg[2] <= events; events_reg[2] <= events;
`endif // `endif
// now figure out the data to be written // now figure out the data to be written
CLineMemDataByteEn be = replicate(replicate(False)); CLineMemDataByteEn be = replicate(replicate(False));
Line data = unpack(0); Line data = unpack(0);
@@ -432,17 +432,17 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
if(verbose) $display("[Store resp] idx = %x, ", idx, fshow(e)); if(verbose) $display("[Store resp] idx = %x, ", idx, fshow(e));
// perf: store mem latency // perf: store mem latency
let lat <- stMemLatTimer.done(idx); let lat <- stMemLatTimer.done(idx);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
exeStMemLat.incr(zeroExtend(lat)); exeStMemLat.incr(zeroExtend(lat));
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsCore events = unpack(0); EventsCore events = unpack(0);
if (pack(e.byteEn) == -1) events.evt_MEM_CAP_STORE = 1; if (pack(e.byteEn) == -1) events.evt_MEM_CAP_STORE = 1;
events.evt_STORE_WAIT = saturating_truncate(lat); events.evt_STORE_WAIT = saturating_truncate(lat);
events_reg[2] <= events; events_reg[2] <= events;
`endif // `endif
return tuple2(unpack(pack(e.byteEn)), e.line); // return SB entry return tuple2(unpack(pack(e.byteEn)), e.line); // return SB entry
endmethod endmethod
`endif `endif
@@ -504,12 +504,12 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
spec_bits: x.spec_bits spec_bits: x.spec_bits
}); });
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// perf: load to use latency // perf: load to use latency
if(x.data.ldstq_tag matches tagged Ld .idx) begin if(x.data.ldstq_tag matches tagged Ld .idx) begin
ldToUseLatTimer.start(idx); ldToUseLatTimer.start(idx);
end end
`endif // `endif
endrule endrule
`ifdef RVFI `ifdef RVFI
@@ -584,11 +584,11 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
if(x.ldstq_tag matches tagged St .stTag) begin if(x.ldstq_tag matches tagged St .stTag) begin
MemTaggedData d = x.mem_func == Amo ? toMemData : shiftData; // XXX don't shift for AMO MemTaggedData d = x.mem_func == Amo ? toMemData : shiftData; // XXX don't shift for AMO
lsq.updateData(stTag, d); lsq.updateData(stTag, d);
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsCore events = unpack(0); EventsCore events = unpack(0);
events.evt_MEM_CAP_STORE_TAG_SET = (d.tag) ? 1 : 0; events.evt_MEM_CAP_STORE_TAG_SET = (d.tag) ? 1 : 0;
events_reg[4] <= events; events_reg[4] <= events;
`endif // `endif
end end
`ifdef KONATA `ifdef KONATA
@@ -808,7 +808,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
); );
let pc = inIfc.rob_getPC(x.tag); let pc = inIfc.rob_getPC(x.tag);
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
function Bool is_16b_inst (Bit #(n) inst); function Bool is_16b_inst (Bit #(n) inst);
return (inst [1:0] != 2'b11); return (inst [1:0] != 2'b11);
@@ -822,7 +822,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
events_trans_reg <= events_trans; events_trans_reg <= events_trans;
end end
`endif `endif
`endif // `endif
`ifdef KONATA `ifdef KONATA
$display("KONATAE\t%0d\t%0d\t0\tMem3", cur_cycle, x.u_id); $display("KONATAE\t%0d\t%0d\t0\tMem3", cur_cycle, x.u_id);
@@ -859,11 +859,11 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
}); });
end end
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(isValid(cause) && inIfc.doStats) begin if(isValid(cause) && inIfc.doStats) begin
exeTlbExcepCnt.incr(1); exeTlbExcepCnt.incr(1);
end end
`endif // `endif
endrule endrule
//======================================================= //=======================================================
@@ -886,10 +886,10 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
`else `else
SBSearchRes sbRes = stb.search(info.paddr, info.shiftedBE); SBSearchRes sbRes = stb.search(info.paddr, info.shiftedBE);
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsCore events = unpack(0); EventsCore events = unpack(0);
if (info.shiftedBE == DataMemAccess (unpack(~0))) events.evt_MEM_CAP_LOAD = 1; if (info.shiftedBE == DataMemAccess (unpack(~0))) events.evt_MEM_CAP_LOAD = 1;
`endif // `endif
// search LSQ // search LSQ
LSQIssueLdResult issRes <- lsq.issueLd(info.tag, info.paddr, info.shiftedBE, sbRes); LSQIssueLdResult issRes <- lsq.issueLd(info.tag, info.paddr, info.shiftedBE, sbRes);
if(verbose) begin if(verbose) begin
@@ -903,12 +903,12 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
if(forward.dst matches tagged Valid .dst) begin if(forward.dst matches tagged Valid .dst) begin
inIfc.setRegReadyAggr_forward(dst.indx); inIfc.setRegReadyAggr_forward(dst.indx);
end end
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// perf: load forward // perf: load forward
if(inIfc.doStats) begin if(inIfc.doStats) begin
exeLdForwardCnt.incr(1); exeLdForwardCnt.incr(1);
end end
`endif // `endif
end end
else if(issRes == ToCache) begin else if(issRes == ToCache) begin
reqLdQ.enq(tuple4(zeroExtend(info.tag), info.paddr, info.shiftedBE == TagMemAccess, info.pcHash)); reqLdQ.enq(tuple4(zeroExtend(info.tag), info.paddr, info.shiftedBE == TagMemAccess, info.pcHash));
@@ -916,7 +916,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
ldMemLatTimer.start(info.tag); ldMemLatTimer.start(info.tag);
end end
else if(issRes matches tagged Stall .stallBy) begin else if(issRes matches tagged Stall .stallBy) begin
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// perf: load stall // perf: load stall
if(inIfc.doStats) begin if(inIfc.doStats) begin
case(stallBy) case(stallBy)
@@ -926,14 +926,14 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
default: doAssert(False, "unknow stall reason"); default: doAssert(False, "unknow stall reason");
endcase endcase
end end
`endif // `endif
end end
else begin else begin
doAssert(False, "load is stalled"); doAssert(False, "load is stalled");
end end
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
events_reg[0] <= events; events_reg[0] <= events;
`endif // `endif
endaction endaction
endfunction endfunction
@@ -975,14 +975,14 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
inIfc.rob_setExecuted_doFinishMem_RegData (res.instTag, res.data); inIfc.rob_setExecuted_doFinishMem_RegData (res.instTag, res.data);
`endif `endif
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// perf: load to use latency // perf: load to use latency
let lat <- ldToUseLatTimer.done(tag); let lat <- ldToUseLatTimer.done(tag);
if(inIfc.doStats) begin if(inIfc.doStats) begin
exeLdToUseLat.incr(zeroExtend(lat)); exeLdToUseLat.incr(zeroExtend(lat));
exeLdToUseCnt.incr(1); exeLdToUseCnt.incr(1);
end end
`endif // `endif
`ifdef RVFI `ifdef RVFI
LdStQTag idx = tagged Ld tag; LdStQTag idx = tagged Ld tag;
memData[pack(idx)] <= truncate(pack(res.data)); // TODO use fromMem? memData[pack(idx)] <= truncate(pack(res.data)); // TODO use fromMem?
@@ -1093,7 +1093,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
if(verbose) $display("[doDeqLdQ_Lr_issue] ", fshow(lsqDeqLd), "; ", fshow(req)); if(verbose) $display("[doDeqLdQ_Lr_issue] ", fshow(lsqDeqLd), "; ", fshow(req));
// check // check
doAssert(!isValid(lsqDeqLd.killed), "cannot be killed"); doAssert(!isValid(lsqDeqLd.killed), "cannot be killed");
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
if(lsqDeqLd.acq) begin if(lsqDeqLd.acq) begin
exeLrScAmoAcqCnt.incr(1); exeLrScAmoAcqCnt.incr(1);
@@ -1102,7 +1102,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
exeLrScAmoRelCnt.incr(1); exeLrScAmoRelCnt.incr(1);
end end
end end
`endif // `endif
endrule endrule
`ifdef SELF_INV_CACHE `ifdef SELF_INV_CACHE
@@ -1384,7 +1384,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
`endif `endif
); );
if(verbose) $display("[doDeqStQ_Fence] ", fshow(lsqDeqSt)); if(verbose) $display("[doDeqStQ_Fence] ", fshow(lsqDeqSt));
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
exeFenceCnt.incr(1); exeFenceCnt.incr(1);
if(lsqDeqSt.acq) begin if(lsqDeqSt.acq) begin
@@ -1394,7 +1394,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
exeFenceRelCnt.incr(1); exeFenceRelCnt.incr(1);
end end
end end
`endif // `endif
endrule endrule
// issue non-MMIO Sc/Amo without fault when // issue non-MMIO Sc/Amo without fault when
@@ -1437,7 +1437,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
}; };
reqLrScAmoQ.enq(req); reqLrScAmoQ.enq(req);
if(verbose) $display("[doDeqStQ_ScAmo_issue] ", fshow(lsqDeqSt), "; ", fshow(req)); if(verbose) $display("[doDeqStQ_ScAmo_issue] ", fshow(lsqDeqSt), "; ", fshow(req));
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
if(lsqDeqSt.acq) begin if(lsqDeqSt.acq) begin
exeLrScAmoAcqCnt.incr(1); exeLrScAmoAcqCnt.incr(1);
@@ -1446,7 +1446,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
exeLrScAmoRelCnt.incr(1); exeLrScAmoRelCnt.incr(1);
end end
end end
`endif // `endif
endrule endrule
`ifdef SELF_INV_CACHE `ifdef SELF_INV_CACHE
@@ -1499,16 +1499,16 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
!lsqDeqSt.isMMIO, "must be non-MMIO Sc/Amo"); !lsqDeqSt.isMMIO, "must be non-MMIO Sc/Amo");
doAssert(!isValid(lsqDeqSt.fault), "no fault"); doAssert(!isValid(lsqDeqSt.fault), "no fault");
// stats for successful SC // stats for successful SC
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats && lsqDeqSt.memFunc == Sc && resp == fromInteger(valueof(ScSuccVal))) begin if(inIfc.doStats && lsqDeqSt.memFunc == Sc && resp == fromInteger(valueof(ScSuccVal))) begin
exeScSuccessCnt.incr(1); exeScSuccessCnt.incr(1);
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsCore events = unpack(0); EventsCore events = unpack(0);
events.evt_SC_SUCCESS = 1; events.evt_SC_SUCCESS = 1;
events_reg[3] <= events; events_reg[3] <= events;
`endif // `endif
endrule endrule
// issue MMIO St/Amo when // issue MMIO St/Amo when
@@ -1546,7 +1546,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
if(verbose) $display("[doDeqStQ_MMIO_issue] ", fshow(lsqDeqSt), "; ", fshow(req)); if(verbose) $display("[doDeqStQ_MMIO_issue] ", fshow(lsqDeqSt), "; ", fshow(req));
// MMIO may cause exception, must have spec tag, and only can be St/Amo // MMIO may cause exception, must have spec tag, and only can be St/Amo
doAssert(lsqDeqSt.memFunc == St || lsqDeqSt.memFunc == Amo, "must be St/Amo"); doAssert(lsqDeqSt.memFunc == St || lsqDeqSt.memFunc == Amo, "must be St/Amo");
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
if(lsqDeqSt.acq) begin if(lsqDeqSt.acq) begin
exeLrScAmoAcqCnt.incr(1); exeLrScAmoAcqCnt.incr(1);
@@ -1555,7 +1555,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
exeLrScAmoRelCnt.incr(1); exeLrScAmoRelCnt.incr(1);
end end
end end
`endif // `endif
endrule endrule
`ifdef SELF_INV_CACHE `ifdef SELF_INV_CACHE
@@ -1725,7 +1725,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
method Data getPerf(ExeStagePerfType t); method Data getPerf(ExeStagePerfType t);
return (case(t) return (case(t)
`ifdef PERF_COUNT // `ifdef PERF_COUNT
ExeLdStallByLd: exeLdStallByLdCnt; ExeLdStallByLd: exeLdStallByLdCnt;
ExeLdStallBySt: exeLdStallByStCnt; ExeLdStallBySt: exeLdStallByStCnt;
ExeLdStallBySB: exeLdStallBySBCnt; ExeLdStallBySB: exeLdStallBySBCnt;
@@ -1741,14 +1741,14 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
ExeFenceAcqCnt: exeFenceAcqCnt; ExeFenceAcqCnt: exeFenceAcqCnt;
ExeFenceRelCnt: exeFenceRelCnt; ExeFenceRelCnt: exeFenceRelCnt;
ExeFenceCnt: exeFenceCnt; ExeFenceCnt: exeFenceCnt;
`endif // `endif
default: 0; default: 0;
endcase); endcase);
endmethod endmethod
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method events = events_reg[0]; method events = events_reg[0];
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
method events_trans = events_trans_reg; method events_trans = events_trans_reg;
`endif `endif
`endif // `endif
endmodule endmodule

View File

@@ -73,10 +73,10 @@ import ConfigReg::*;
import CHERICap::*; import CHERICap::*;
import CHERICC_Fat::*; import CHERICC_Fat::*;
import ISA_Decls_CHERI::*; import ISA_Decls_CHERI::*;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import StatCounters::*; import StatCounters::*;
import DReg::*; import DReg::*;
`endif // `endif
import Cur_Cycle :: *; import Cur_Cycle :: *;
@@ -116,9 +116,9 @@ interface RenameStage;
// performance count // performance count
method Data getPerf(ExeStagePerfType t); method Data getPerf(ExeStagePerfType t);
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsTransExe events; method EventsTransExe events;
`endif // `endif
// deadlock check // deadlock check
interface Get#(RenameStuck) renameInstStuck; interface Get#(RenameStuck) renameInstStuck;
@@ -150,15 +150,15 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
// performance counter // performance counter
Count#(Data) supRenameCnt <- mkCount(0); Count#(Data) supRenameCnt <- mkCount(0);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
`ifdef SECURITY `ifdef SECURITY
Count#(Data) specNoneCycles <- mkCount(0); Count#(Data) specNoneCycles <- mkCount(0);
Count#(Data) specNonMemCycles <- mkCount(0); Count#(Data) specNonMemCycles <- mkCount(0);
`endif `endif
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
Reg#(EventsTransExe) events_reg <- mkDReg(unpack(0)); Reg#(EventsTransExe) events_reg <- mkDReg(unpack(0));
`endif // `endif
// deadlock check // deadlock check
`ifdef CHECK_DEADLOCK `ifdef CHECK_DEADLOCK
// timer to check deadlock // timer to check deadlock
@@ -421,7 +421,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
end end
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
`ifdef CONTRACTS_VERIFY `ifdef CONTRACTS_VERIFY
let validPc = (x.orig_inst[1:0] != 2'b11) ? addPc(pc,2) : addPc(pc,4); let validPc = (x.orig_inst[1:0] != 2'b11) ? addPc(pc,2) : addPc(pc,4);
if((ppc != validPc)) begin if((ppc != validPc)) begin
@@ -430,7 +430,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
events_reg <= events; events_reg <= events;
end end
`endif `endif
`endif // `endif
`ifdef CHECK_DEADLOCK `ifdef CHECK_DEADLOCK
renameCorrectPath.send; renameCorrectPath.send;
@@ -636,11 +636,11 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
$display("KONATAS\t%0d\t%d\t0\tRnm", cur_cycle, x.u_id); $display("KONATAS\t%0d\t%d\t0\tRnm", cur_cycle, x.u_id);
$fflush; $fflush;
`endif `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsTransExe events = unpack(0); EventsTransExe events = unpack(0);
events.evt_RENAMED_INST = 1; events.evt_RENAMED_INST = 1;
events_reg <= events; events_reg <= events;
`endif // `endif
// record if we issue an CSR inst. TODO also for SCRs? // record if we issue an CSR inst. TODO also for SCRs?
if(dInst.iType == Csr) begin if(dInst.iType == Csr) begin
@@ -660,14 +660,14 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
Bool specNone = !machineMode && csrf.rd(csrAddrMSPEC) == zeroExtend(mSpecNone); Bool specNone = !machineMode && csrf.rd(csrAddrMSPEC) == zeroExtend(mSpecNone);
Bool specNonMem = machineMode || csrf.rd(csrAddrMSPEC) == zeroExtend(mSpecNonMem); Bool specNonMem = machineMode || csrf.rd(csrAddrMSPEC) == zeroExtend(mSpecNonMem);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
rule incSpecNoneCycles(inIfc.doStats && specNone); rule incSpecNoneCycles(inIfc.doStats && specNone);
specNoneCycles.incr(1); specNoneCycles.incr(1);
endrule endrule
rule incSpecNonMemCycles(inIfc.doStats && specNonMem); rule incSpecNonMemCycles(inIfc.doStats && specNonMem);
specNonMemCycles.incr(1); specNonMemCycles.incr(1);
endrule endrule
`endif // `endif
// first inst is mem inst // first inst is mem inst
function Bool isMemInst(ExecFunc f); function Bool isMemInst(ExecFunc f);
@@ -1251,20 +1251,20 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
// otherwise this rule may block other rules forever // otherwise this rule may block other rules forever
when(doCorrectPath, noAction); when(doCorrectPath, noAction);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(inIfc.doStats) begin if(inIfc.doStats) begin
if(renameCnt > 1) begin if(renameCnt > 1) begin
supRenameCnt.incr(1); supRenameCnt.incr(1);
end end
end end
`else // `else
supRenameCnt.incr(zeroExtend(renameCnt)); // supRenameCnt.incr(zeroExtend(renameCnt));
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsTransExe events = unpack(0); EventsTransExe events = unpack(0);
events.evt_RENAMED_INST = zeroExtend(renameCnt); events.evt_RENAMED_INST = zeroExtend(renameCnt);
events_reg <= events; events_reg <= events;
`endif // `endif
`ifdef CHECK_DEADLOCK `ifdef CHECK_DEADLOCK
if(doCorrectPath) begin if(doCorrectPath) begin
@@ -1284,20 +1284,20 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
method Data getPerf(ExeStagePerfType t); method Data getPerf(ExeStagePerfType t);
return (case(t) return (case(t)
`ifdef PERF_COUNT // `ifdef PERF_COUNT
SupRenameCnt: supRenameCnt; SupRenameCnt: supRenameCnt;
`ifdef SECURITY `ifdef SECURITY
SpecNoneCycles: specNoneCycles; SpecNoneCycles: specNoneCycles;
SpecNonMemCycles: specNoneCycles; SpecNonMemCycles: specNoneCycles;
`endif `endif
`endif // `endif
default: 0; default: 0;
endcase); endcase);
endmethod endmethod
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method events = events_reg; method events = events_reg;
`endif // `endif
`ifdef INCLUDE_GDB_CONTROL `ifdef INCLUDE_GDB_CONTROL
method Action debug_halt_req (); method Action debug_halt_req ();

View File

@@ -52,12 +52,12 @@ import LatencyTimer::*;
import HasSpecBits::*; import HasSpecBits::*;
import Vector::*; import Vector::*;
import Ehr::*; import Ehr::*;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*; import PerformanceMonitor::*;
import CCTypes::*; import CCTypes::*;
import BlueUtils::*; import BlueUtils::*;
import StatCounters::*; import StatCounters::*;
`endif // `endif
export DTlbReq(..); export DTlbReq(..);
export DTlbResp(..); export DTlbResp(..);
@@ -123,9 +123,9 @@ interface DTlb#(type instT);
// performance // performance
interface Perf#(L1TlbPerfType) perf; interface Perf#(L1TlbPerfType) perf;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsL1D events; method EventsL1D events;
`endif // `endif
endinterface endinterface
typedef FullAssocTlb#(DTlbSize) DTlbArray; typedef FullAssocTlb#(DTlbSize) DTlbArray;
@@ -210,7 +210,7 @@ module mkDTlb#(
// perf counters // perf counters
LatencyTimer#(DTlbReqNum, 12) latTimer <- mkLatencyTimer; // max latency: 4K cycles LatencyTimer#(DTlbReqNum, 12) latTimer <- mkLatencyTimer; // max latency: 4K cycles
Fifo#(1, L1TlbPerfType) perfReqQ <- mkCFFifo; Fifo#(1, L1TlbPerfType) perfReqQ <- mkCFFifo;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
Fifo#(1, PerfResp#(L1TlbPerfType)) perfRespQ <- mkCFFifo; Fifo#(1, PerfResp#(L1TlbPerfType)) perfRespQ <- mkCFFifo;
Reg#(Bool) doStats <- mkConfigReg(False); Reg#(Bool) doStats <- mkConfigReg(False);
Count#(Data) accessCnt <- mkCount(0); Count#(Data) accessCnt <- mkCount(0);
@@ -250,11 +250,12 @@ module mkDTlb#(
rule incrAllMissCycles(doStats); rule incrAllMissCycles(doStats);
function Bool isMiss(DTlbWait x) = x != None; function Bool isMiss(DTlbWait x) = x != None;
when(all(isMiss, readVReg(pendWait)), allMissCycles.incr(1)); when(all(isMiss, readVReg(pendWait)), allMissCycles.incr(1));
$display("L1TlballMissCycles = %0d", allMissCycles);
endrule endrule
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
Array #(Reg #(EventsL1D)) perf_events <- mkDRegOR (3, unpack (0)); Array #(Reg #(EventsL1D)) perf_events <- mkDRegOR (3, unpack (0));
`endif // `endif
// do flush: start when all misses resolve // do flush: start when all misses resolve
Bool noMiss = all(\== (False) , readVReg(pendValid_noMiss)); Bool noMiss = all(\== (False) , readVReg(pendValid_noMiss));
@@ -265,11 +266,11 @@ module mkDTlb#(
flushRqToPQ.enq(?); flushRqToPQ.enq(?);
waitFlushP <= True; waitFlushP <= True;
if(verbose) $display("[DTLB] flush begin"); if(verbose) $display("[DTLB] flush begin");
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsL1D ev = unpack(0); EventsL1D ev = unpack(0);
ev.evt_TLB_FLUSH = 1; ev.evt_TLB_FLUSH = 1;
perf_events[2] <= ev; perf_events[2] <= ev;
`endif // `endif
endrule endrule
rule doFinishFlush(needFlush && waitFlushP); rule doFinishFlush(needFlush && waitFlushP);
@@ -365,24 +366,28 @@ module mkDTlb#(
// perf: miss // perf: miss
let lat <- latTimer.done(idx); let lat <- latTimer.done(idx);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
if(isValid(respForOtherReq)) begin if(isValid(respForOtherReq)) begin
$display("L1 TLB miss");
$display("L1TLBmissPeerLat = %0d", missPeerLat);
missPeerLat.incr(zeroExtend(lat)); missPeerLat.incr(zeroExtend(lat));
missPeerCnt.incr(1); missPeerCnt.incr(1);
end end
else begin else begin
missParentLat.incr(zeroExtend(lat)); missParentLat.incr(zeroExtend(lat));
missParentCnt.incr(1); missParentCnt.incr(1);
$display("L1 TLB parent miss");
$display("L1TLBmissParentCnt = %0d", missParentCnt);
end end
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsL1D ev = unpack(0); EventsL1D ev = unpack(0);
ev.evt_TLB_MISS_LAT = saturating_truncate(lat); ev.evt_TLB_MISS_LAT = saturating_truncate(lat);
ev.evt_TLB_MISS = 1; ev.evt_TLB_MISS = 1;
perf_events[0] <= ev; perf_events[0] <= ev;
`endif // `endif
// conflict with wrong spec // conflict with wrong spec
wrongSpec_doPRs_conflict.wset(?); wrongSpec_doPRs_conflict.wset(?);
endrule endrule
@@ -573,17 +578,18 @@ module mkDTlb#(
if(verbose) $display("DTLB %m req (bare): ", fshow(r)); if(verbose) $display("DTLB %m req (bare): ", fshow(r));
end end
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// perf: access // perf: access
if(doStats) begin if(doStats) begin
$display("L1 TLB inc");
accessCnt.incr(1); accessCnt.incr(1);
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsL1D ev = unpack(0); EventsL1D ev = unpack(0);
ev.evt_TLB = 1; ev.evt_TLB = 1;
perf_events[1] <= ev; perf_events[1] <= ev;
`endif // `endif
// conflict with wrong spec // conflict with wrong spec
wrongSpec_procReq_conflict.wset(?); wrongSpec_procReq_conflict.wset(?);
endmethod endmethod
@@ -640,11 +646,11 @@ module mkDTlb#(
interface Perf perf; interface Perf perf;
method Action setStatus(Bool stats); method Action setStatus(Bool stats);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
doStats <= stats; doStats <= stats;
`else // `else
noAction; // noAction;
`endif // `endif
endmethod endmethod
method Action req(L1TlbPerfType r); method Action req(L1TlbPerfType r);
@@ -652,27 +658,27 @@ module mkDTlb#(
endmethod endmethod
method ActionValue#(PerfResp#(L1TlbPerfType)) resp; method ActionValue#(PerfResp#(L1TlbPerfType)) resp;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
perfRespQ.deq; perfRespQ.deq;
return perfRespQ.first; return perfRespQ.first;
`else // `else
perfReqQ.deq; // perfReqQ.deq;
return PerfResp { // return PerfResp {
pType: perfReqQ.first, // pType: perfReqQ.first,
data: 0 // data: 0
}; // };
`endif // `endif
endmethod endmethod
method Bool respValid; method Bool respValid;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
return perfRespQ.notEmpty; return perfRespQ.notEmpty;
`else // `else
return perfReqQ.notEmpty; // return perfReqQ.notEmpty;
`endif // `endif
endmethod endmethod
endinterface endinterface
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsL1D events = perf_events[0]; method EventsL1D events = perf_events[0];
`endif // `endif
endmodule endmodule

View File

@@ -0,0 +1,186 @@
diff a/src_Core/RISCY_OOO/procs/lib/DTlb.bsv b/src_Core/RISCY_OOO/procs/lib/DTlb.bsv (rejected hunks)
@@ -52,12 +52,12 @@ import LatencyTimer::*;
import HasSpecBits::*;
import Vector::*;
import Ehr::*;
-`ifdef PERFORMANCE_MONITORING
+// `ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*;
import CCTypes::*;
import BlueUtils::*;
import StatCounters::*;
-`endif
+// `endif
export DTlbReq(..);
export DTlbResp(..);
@@ -123,9 +123,9 @@ interface DTlb#(type instT);
// performance
interface Perf#(L1TlbPerfType) perf;
-`ifdef PERFORMANCE_MONITORING
+// `ifdef PERFORMANCE_MONITORING
method EventsL1D events;
-`endif
+// `endif
endinterface
typedef FullAssocTlb#(DTlbSize) DTlbArray;
@@ -210,7 +210,7 @@ module mkDTlb#(
// perf counters
LatencyTimer#(DTlbReqNum, 12) latTimer <- mkLatencyTimer; // max latency: 4K cycles
Fifo#(1, L1TlbPerfType) perfReqQ <- mkCFFifo;
-`ifdef PERF_COUNT
+// `ifdef PERF_COUNT
Fifo#(1, PerfResp#(L1TlbPerfType)) perfRespQ <- mkCFFifo;
Reg#(Bool) doStats <- mkConfigReg(False);
Count#(Data) accessCnt <- mkCount(0);
@@ -243,10 +243,10 @@ module mkDTlb#(
function Bool isMiss(DTlbWait x) = x != None;
when(all(isMiss, readVReg(pendWait)), allMissCycles.incr(1));
endrule
-`endif
-`ifdef PERFORMANCE_MONITORING
+// `endif
+// `ifdef PERFORMANCE_MONITORING
Array #(Reg #(EventsL1D)) perf_events <- mkDRegOR (3, unpack (0));
-`endif
+// `endif
// do flush: start when all misses resolve
Bool noMiss = all(\== (False) , readVReg(pendValid_noMiss));
@@ -257,11 +257,11 @@ module mkDTlb#(
flushRqToPQ.enq(?);
waitFlushP <= True;
if(verbose) $display("[DTLB] flush begin");
-`ifdef PERFORMANCE_MONITORING
+// `ifdef PERFORMANCE_MONITORING
EventsL1D ev = unpack(0);
ev.evt_TLB_FLUSH = 1;
perf_events[2] <= ev;
-`endif
+// `endif
endrule
rule doFinishFlush(needFlush && waitFlushP);
@@ -357,7 +357,7 @@ module mkDTlb#(
// perf: miss
let lat <- latTimer.done(idx);
-`ifdef PERF_COUNT
+// `ifdef PERF_COUNT
if(doStats) begin
if(isValid(respForOtherReq)) begin
missPeerLat.incr(zeroExtend(lat));
@@ -368,13 +368,13 @@ module mkDTlb#(
missParentCnt.incr(1);
end
end
-`endif
-`ifdef PERFORMANCE_MONITORING
+// `endif
+// `ifdef PERFORMANCE_MONITORING
EventsL1D ev = unpack(0);
ev.evt_TLB_MISS_LAT = saturating_truncate(lat);
ev.evt_TLB_MISS = 1;
perf_events[0] <= ev;
-`endif
+// `endif
// conflict with wrong spec
wrongSpec_doPRs_conflict.wset(?);
endrule
@@ -508,12 +508,12 @@ module mkDTlb#(
$display("[DTLB] req (hit): idx %d; ", idx, fshow(r),
"; ", fshow(trans_result));
end
-`ifdef PERF_COUNT
+// `ifdef PERF_COUNT
// perf: hit under miss
if(doStats && readVReg(pendWait) != replicate(None)) begin
hitUnderMissCnt.incr(1);
end
-`endif
+// `endif
end
else begin
// page fault
@@ -565,17 +565,17 @@ module mkDTlb#(
if(verbose) $display("DTLB %m req (bare): ", fshow(r));
end
-`ifdef PERF_COUNT
+// `ifdef PERF_COUNT
// perf: access
if(doStats) begin
accessCnt.incr(1);
end
-`endif
-`ifdef PERFORMANCE_MONITORING
+// `endif
+// `ifdef PERFORMANCE_MONITORING
EventsL1D ev = unpack(0);
ev.evt_TLB = 1;
perf_events[1] <= ev;
-`endif
+// `endif
// conflict with wrong spec
wrongSpec_procReq_conflict.wset(?);
endmethod
@@ -632,11 +632,11 @@ module mkDTlb#(
interface Perf perf;
method Action setStatus(Bool stats);
-`ifdef PERF_COUNT
+// `ifdef PERF_COUNT
doStats <= stats;
-`else
- noAction;
-`endif
+// `else
+// noAction;
+// `endif
endmethod
method Action req(L1TlbPerfType r);
@@ -644,27 +644,27 @@ module mkDTlb#(
endmethod
method ActionValue#(PerfResp#(L1TlbPerfType)) resp;
-`ifdef PERF_COUNT
+// `ifdef PERF_COUNT
perfRespQ.deq;
return perfRespQ.first;
-`else
- perfReqQ.deq;
- return PerfResp {
- pType: perfReqQ.first,
- data: 0
- };
-`endif
+// `else
+// perfReqQ.deq;
+// return PerfResp {
+// pType: perfReqQ.first,
+// data: 0
+// };
+// `endif
endmethod
method Bool respValid;
-`ifdef PERF_COUNT
+// `ifdef PERF_COUNT
return perfRespQ.notEmpty;
-`else
- return perfReqQ.notEmpty;
-`endif
+// `else
+// return perfReqQ.notEmpty;
+// `endif
endmethod
endinterface
-`ifdef PERFORMANCE_MONITORING
+// `ifdef PERFORMANCE_MONITORING
method EventsL1D events = perf_events[0];
-`endif
+// `endif
endmodule

View File

@@ -50,12 +50,12 @@ import Cntrs::*;
import SafeCounter::*; import SafeCounter::*;
import CacheUtils::*; import CacheUtils::*;
import LatencyTimer::*; import LatencyTimer::*;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*; import PerformanceMonitor::*;
import CCTypes::*; import CCTypes::*;
import BlueUtils::*; import BlueUtils::*;
import StatCounters::*; import StatCounters::*;
`endif // `endif
// currently blocking // currently blocking
typedef `L1_TLB_SIZE ITlbSize; typedef `L1_TLB_SIZE ITlbSize;
@@ -92,9 +92,9 @@ interface ITlb;
// performance // performance
interface Perf#(L1TlbPerfType) perf; interface Perf#(L1TlbPerfType) perf;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsL1I events; method EventsL1I events;
`endif // `endif
endinterface endinterface
typedef FullAssocTlb#(ITlbSize) ITlbArray; typedef FullAssocTlb#(ITlbSize) ITlbArray;
@@ -134,7 +134,7 @@ module mkITlb(ITlb::ITlb);
// perf counters // perf counters
LatencyTimer#(2, 12) latTimer <- mkLatencyTimer; // max latency: 4K cycles LatencyTimer#(2, 12) latTimer <- mkLatencyTimer; // max latency: 4K cycles
Fifo#(1, L1TlbPerfType) perfReqQ <- mkCFFifo; Fifo#(1, L1TlbPerfType) perfReqQ <- mkCFFifo;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
Fifo#(1, PerfResp#(L1TlbPerfType)) perfRespQ <- mkCFFifo; Fifo#(1, PerfResp#(L1TlbPerfType)) perfRespQ <- mkCFFifo;
Reg#(Bool) doStats <- mkConfigReg(False); Reg#(Bool) doStats <- mkConfigReg(False);
Count#(Data) accessCnt <- mkCount(0); Count#(Data) accessCnt <- mkCount(0);
@@ -154,10 +154,10 @@ module mkITlb(ITlb::ITlb);
data: d data: d
}); });
endrule endrule
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
Array #(Reg #(EventsL1I)) perf_events <- mkDRegOR (3, unpack (0)); Array #(Reg #(EventsL1I)) perf_events <- mkDRegOR (3, unpack (0));
`endif // `endif
// do flush: only start when all misses resolve // do flush: only start when all misses resolve
rule doStartFlush(needFlush && !waitFlushP && !isValid(miss)); rule doStartFlush(needFlush && !waitFlushP && !isValid(miss));
@@ -166,11 +166,11 @@ module mkITlb(ITlb::ITlb);
flushRqToPQ.enq(?); flushRqToPQ.enq(?);
waitFlushP <= True; waitFlushP <= True;
if(verbose) $display("ITLB %m: flush begin"); if(verbose) $display("ITLB %m: flush begin");
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsL1I ev = unpack(0); EventsL1I ev = unpack(0);
ev.evt_TLB_FLUSH = 1; ev.evt_TLB_FLUSH = 1;
perf_events[2] <= ev; perf_events[2] <= ev;
`endif // `endif
endrule endrule
rule doFinishFlush(needFlush && waitFlushP && !isValid(miss)); rule doFinishFlush(needFlush && waitFlushP && !isValid(miss));
@@ -225,17 +225,17 @@ module mkITlb(ITlb::ITlb);
miss <= Invalid; miss <= Invalid;
let lat <- latTimer.done(0); let lat <- latTimer.done(0);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
missLat.incr(zeroExtend(lat)); missLat.incr(zeroExtend(lat));
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsL1I ev = unpack(0); EventsL1I ev = unpack(0);
ev.evt_TLB_MISS_LAT = saturating_truncate(lat); ev.evt_TLB_MISS_LAT = saturating_truncate(lat);
ev.evt_TLB_MISS = 1; ev.evt_TLB_MISS = 1;
perf_events[0] <= ev; perf_events[0] <= ev;
`endif // `endif
endrule endrule
// we check no pending req only at Commit when Fetch1 stage has been // we check no pending req only at Commit when Fetch1 stage has been
@@ -345,11 +345,11 @@ module mkITlb(ITlb::ITlb);
$display("ITLB %m req (miss): ", fshow(vaddr)); $display("ITLB %m req (miss): ", fshow(vaddr));
end end
latTimer.start(0); latTimer.start(0);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
missCnt.incr(1); missCnt.incr(1);
end end
`endif // `endif
end end
end end
else begin else begin
@@ -358,16 +358,16 @@ module mkITlb(ITlb::ITlb);
if (verbose) $display("ITLB %m req (bare): ", fshow(vaddr)); if (verbose) $display("ITLB %m req (bare): ", fshow(vaddr));
end end
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
accessCnt.incr(1); accessCnt.incr(1);
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsL1I ev = unpack(0); EventsL1I ev = unpack(0);
ev.evt_TLB = 1; ev.evt_TLB = 1;
perf_events[1] <= ev; perf_events[1] <= ev;
`endif // `endif
endmethod endmethod
endinterface endinterface
interface Get response = toGet(hitQ); interface Get response = toGet(hitQ);
@@ -384,11 +384,11 @@ module mkITlb(ITlb::ITlb);
interface Perf perf; interface Perf perf;
method Action setStatus(Bool stats); method Action setStatus(Bool stats);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
doStats <= stats; doStats <= stats;
`else // `else
noAction; // noAction;
`endif // `endif
endmethod endmethod
method Action req(L1TlbPerfType r); method Action req(L1TlbPerfType r);
@@ -396,27 +396,27 @@ module mkITlb(ITlb::ITlb);
endmethod endmethod
method ActionValue#(PerfResp#(L1TlbPerfType)) resp; method ActionValue#(PerfResp#(L1TlbPerfType)) resp;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
perfRespQ.deq; perfRespQ.deq;
return perfRespQ.first; return perfRespQ.first;
`else // `else
perfReqQ.deq; // perfReqQ.deq;
return PerfResp { // return PerfResp {
pType: perfReqQ.first, // pType: perfReqQ.first,
data: 0 // data: 0
}; // };
`endif // `endif
endmethod endmethod
method Bool respValid; method Bool respValid;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
return perfRespQ.notEmpty; return perfRespQ.notEmpty;
`else // `else
return perfReqQ.notEmpty; // return perfReqQ.notEmpty;
`endif // `endif
endmethod endmethod
endinterface endinterface
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsL1I events = perf_events[0]; method EventsL1I events = perf_events[0];
`endif // `endif
endmodule endmodule

View File

@@ -59,9 +59,9 @@ import SelfInvL1Pipe::*;
import SelfInvL1Bank::*; import SelfInvL1Bank::*;
import SelfInvIPipe::*; import SelfInvIPipe::*;
import SelfInvIBank::*; import SelfInvIBank::*;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import StatCounters::*; import StatCounters::*;
`endif // `endif
export L1Num; export L1Num;
export LgL1WayNum; export LgL1WayNum;
@@ -188,9 +188,9 @@ interface DCoCache;
method Bool flush_done; method Bool flush_done;
method Action resetLinkAddr; method Action resetLinkAddr;
interface Perf#(L1DPerfType) perf; interface Perf#(L1DPerfType) perf;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsL1D events; method EventsL1D events;
`endif // `endif
interface ChildCacheToParent#(L1Way, void) to_parent; interface ChildCacheToParent#(L1Way, void) to_parent;
@@ -208,7 +208,7 @@ module mkDCoCache#(L1ProcResp#(DProcReqId) procResp)(DCoCache);
// perf counters // perf counters
Fifo#(1, L1DPerfType) perfReqQ <- mkCFFifo; Fifo#(1, L1DPerfType) perfReqQ <- mkCFFifo;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
Fifo#(1, PerfResp#(L1DPerfType)) perfRespQ <- mkCFFifo; Fifo#(1, PerfResp#(L1DPerfType)) perfRespQ <- mkCFFifo;
rule doPerf; rule doPerf;
@@ -219,7 +219,7 @@ module mkDCoCache#(L1ProcResp#(DProcReqId) procResp)(DCoCache);
data: d data: d
}); });
endrule endrule
`endif // `endif
`ifdef SELF_INV_CACHE `ifdef SELF_INV_CACHE
// change the reconcile ifc to a FIFO ifc to avoid scheduling issues // change the reconcile ifc to a FIFO ifc to avoid scheduling issues
@@ -261,28 +261,28 @@ module mkDCoCache#(L1ProcResp#(DProcReqId) procResp)(DCoCache);
perfReqQ.enq(r); perfReqQ.enq(r);
endmethod endmethod
method ActionValue#(PerfResp#(L1DPerfType)) resp; method ActionValue#(PerfResp#(L1DPerfType)) resp;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
perfRespQ.deq; perfRespQ.deq;
return perfRespQ.first; return perfRespQ.first;
`else // `else
perfReqQ.deq; // perfReqQ.deq;
return PerfResp { // return PerfResp {
pType: perfReqQ.first, // pType: perfReqQ.first,
data: 0 // data: 0
}; // };
`endif // `endif
endmethod endmethod
method Bool respValid; method Bool respValid;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
return perfRespQ.notEmpty; return perfRespQ.notEmpty;
`else // `else
return perfReqQ.notEmpty; // return perfReqQ.notEmpty;
`endif // `endif
endmethod endmethod
endinterface endinterface
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsL1D events = cache.events; method EventsL1D events = cache.events;
`endif // `endif
interface to_parent = cache.to_parent; interface to_parent = cache.to_parent;
@@ -382,9 +382,9 @@ interface ICoCache;
method Action flush; method Action flush;
method Bool flush_done; method Bool flush_done;
interface Perf#(L1IPerfType) perf; interface Perf#(L1IPerfType) perf;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsL1I events; method EventsL1I events;
`endif // `endif
interface ChildCacheToParent#(L1Way, void) to_parent; interface ChildCacheToParent#(L1Way, void) to_parent;
@@ -407,7 +407,7 @@ module mkICoCache(ICoCache);
let cache <- mkIBankWrapper; let cache <- mkIBankWrapper;
Fifo#(1, L1IPerfType) perfReqQ <- mkCFFifo; Fifo#(1, L1IPerfType) perfReqQ <- mkCFFifo;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
Fifo#(1, PerfResp#(L1IPerfType)) perfRespQ <- mkCFFifo; Fifo#(1, PerfResp#(L1IPerfType)) perfRespQ <- mkCFFifo;
rule doPerf; rule doPerf;
@@ -418,7 +418,7 @@ module mkICoCache(ICoCache);
data: d data: d
}); });
endrule endrule
`endif // `endif
interface Server to_proc; interface Server to_proc;
interface request = cache.to_proc.req; interface request = cache.to_proc.req;
@@ -436,28 +436,28 @@ module mkICoCache(ICoCache);
perfReqQ.enq(r); perfReqQ.enq(r);
endmethod endmethod
method ActionValue#(PerfResp#(L1IPerfType)) resp; method ActionValue#(PerfResp#(L1IPerfType)) resp;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
perfRespQ.deq; perfRespQ.deq;
return perfRespQ.first; return perfRespQ.first;
`else // `else
perfReqQ.deq; // perfReqQ.deq;
return PerfResp { // return PerfResp {
pType: perfReqQ.first, // pType: perfReqQ.first,
data: 0 // data: 0
}; // };
`endif // `endif
endmethod endmethod
method Bool respValid; method Bool respValid;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
return perfRespQ.notEmpty; return perfRespQ.notEmpty;
`else // `else
return perfReqQ.notEmpty; // return perfReqQ.notEmpty;
`endif // `endif
endmethod endmethod
endinterface endinterface
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsL1I events = cache.events; method EventsL1I events = cache.events;
`endif // `endif
interface to_parent = cache.to_parent; interface to_parent = cache.to_parent;

View File

@@ -54,12 +54,12 @@ import SetAssocTlb::*;
import L2SetAssocTlb::*; import L2SetAssocTlb::*;
import TranslationCache::*; import TranslationCache::*;
import LatencyTimer::*; import LatencyTimer::*;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*; import PerformanceMonitor::*;
import CCTypes::*; import CCTypes::*;
import BlueUtils::*; import BlueUtils::*;
import StatCounters::*; import StatCounters::*;
`endif // `endif
// for SV39 only // for SV39 only
@@ -120,9 +120,9 @@ interface L2Tlb;
// performace // performace
interface Perf#(L2TlbPerfType) perf; interface Perf#(L2TlbPerfType) perf;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsLL events; method EventsLL events;
`endif // `endif
endinterface endinterface
typedef FullAssocTlb#(`L2_TLB_HUGE_SIZE) L2FullAssocTlb; typedef FullAssocTlb#(`L2_TLB_HUGE_SIZE) L2FullAssocTlb;
@@ -220,7 +220,7 @@ module mkL2Tlb(L2Tlb::L2Tlb);
// FIFO for perf req // FIFO for perf req
Fifo#(1, L2TlbPerfType) perfReqQ <- mkCFFifo; Fifo#(1, L2TlbPerfType) perfReqQ <- mkCFFifo;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
Fifo#(1, PerfResp#(L2TlbPerfType)) perfRespQ <- mkCFFifo; Fifo#(1, PerfResp#(L2TlbPerfType)) perfRespQ <- mkCFFifo;
Reg#(Bool) doStats <- mkConfigReg(False); Reg#(Bool) doStats <- mkConfigReg(False);
Count#(Data) instMissCnt <- mkCount(0); Count#(Data) instMissCnt <- mkCount(0);
@@ -285,10 +285,10 @@ module mkL2Tlb(L2Tlb::L2Tlb);
data: d data: d
}); });
endrule endrule
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
Array #(Reg #(EventsLL)) perf_events <- mkDRegOR (3, unpack (0)); Array #(Reg #(EventsLL)) perf_events <- mkDRegOR (3, unpack (0));
`endif // `endif
// when flushing is true, since both I and D TLBs have finished flush and // when flushing is true, since both I and D TLBs have finished flush and
// is waiting for L2 to flush, all I/D TLB req must have been responded. // is waiting for L2 to flush, all I/D TLB req must have been responded.
@@ -301,11 +301,11 @@ module mkL2Tlb(L2Tlb::L2Tlb);
// check no req // check no req
doAssert(!rqFromCQ.notEmpty, "cannot have new req"); doAssert(!rqFromCQ.notEmpty, "cannot have new req");
doAssert(readVEhr(0, pendValid) == replicate(False), "cannot have pending req"); doAssert(readVEhr(0, pendValid) == replicate(False), "cannot have pending req");
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsLL ev = unpack(0); EventsLL ev = unpack(0);
ev.evt_TLB_FLUSH = 1; ev.evt_TLB_FLUSH = 1;
perf_events[2] <= ev; perf_events[2] <= ev;
`endif // `endif
endrule endrule
rule doWaitFlush(flushing && waitFlushDone && tlb4KB.flush_done && transCache.flush_done); rule doWaitFlush(flushing && waitFlushDone && tlb4KB.flush_done && transCache.flush_done);
@@ -377,7 +377,7 @@ module mkL2Tlb(L2Tlb::L2Tlb);
}); });
// req is done // req is done
pendValid_tlbResp[idx] <= False; pendValid_tlbResp[idx] <= False;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// perf: hit under miss // perf: hit under miss
function Bool otherMiss(L2TlbReqIdx i); function Bool otherMiss(L2TlbReqIdx i);
return pendValid_tlbResp[i] && pendWait_tlbResp[i] != None && i != idx; return pendValid_tlbResp[i] && pendWait_tlbResp[i] != None && i != idx;
@@ -386,7 +386,7 @@ module mkL2Tlb(L2Tlb::L2Tlb);
if(any(otherMiss, idxVec)) begin if(any(otherMiss, idxVec)) begin
hitUnderMissCnt.incr(1); hitUnderMissCnt.incr(1);
end end
`endif // `endif
endaction endaction
endfunction endfunction
@@ -410,7 +410,7 @@ module mkL2Tlb(L2Tlb::L2Tlb);
pageHit(entry); pageHit(entry);
tlb4KB.deqResp(Invalid); // just deq 4KB array tlb4KB.deqResp(Invalid); // just deq 4KB array
tlbMG.updateRepByHit(respMG.index); // update replacement in MG array tlbMG.updateRepByHit(respMG.index); // update replacement in MG array
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
if(cRq.child == I) begin if(cRq.child == I) begin
instHugePageHitCnt.incr(1); instHugePageHitCnt.incr(1);
@@ -419,12 +419,12 @@ module mkL2Tlb(L2Tlb::L2Tlb);
dataHugePageHitCnt.incr(1); dataHugePageHitCnt.incr(1);
end end
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsLL ev = unpack(0); EventsLL ev = unpack(0);
ev.evt_TLB = 1; ev.evt_TLB = 1;
perf_events[1] <= ev; perf_events[1] <= ev;
`endif // `endif
end end
else if(resp4KB.hit) begin else if(resp4KB.hit) begin
// hit on 4KB page // hit on 4KB page
@@ -433,11 +433,11 @@ module mkL2Tlb(L2Tlb::L2Tlb);
pageHit(entry); pageHit(entry);
// update 4KB array replacement, no need to touch MG array // update 4KB array replacement, no need to touch MG array
tlb4KB.deqResp(Valid (resp4KB.way)); tlb4KB.deqResp(Valid (resp4KB.way));
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsLL ev = unpack(0); EventsLL ev = unpack(0);
ev.evt_TLB = 1; ev.evt_TLB = 1;
perf_events[1] <= ev; perf_events[1] <= ev;
`endif // `endif
end end
else begin else begin
// miss, deq resp // miss, deq resp
@@ -446,7 +446,7 @@ module mkL2Tlb(L2Tlb::L2Tlb);
transCache.req(cRq.vpn, vm_info.asid); transCache.req(cRq.vpn, vm_info.asid);
transCacheReqQ.enq(idx); transCacheReqQ.enq(idx);
// perf: TLB miss // perf: TLB miss
`ifdef PERF_COUNT // `ifdef PERF_COUNT
latTimer.start(idx); latTimer.start(idx);
if(doStats) begin if(doStats) begin
if(cRq.child == I) begin if(cRq.child == I) begin
@@ -456,12 +456,12 @@ module mkL2Tlb(L2Tlb::L2Tlb);
dataMissCnt.incr(1); dataMissCnt.incr(1);
end end
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsLL ev = unpack(0); EventsLL ev = unpack(0);
ev.evt_TLB_MISS = 1; ev.evt_TLB_MISS = 1;
perf_events[0] <= ev; perf_events[0] <= ev;
`endif // `endif
end end
endrule endrule
@@ -517,11 +517,11 @@ module mkL2Tlb(L2Tlb::L2Tlb);
// duplicate req // duplicate req
pendWait_transCacheResp[idx] <= WaitPeer (i); pendWait_transCacheResp[idx] <= WaitPeer (i);
doAssert(pendValid_transCacheResp[i], "peer must be valid"); doAssert(pendValid_transCacheResp[i], "peer must be valid");
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
peerSavedMemReqCnt.incr(1); peerSavedMemReqCnt.incr(1);
end end
`endif // `endif
end end
else begin else begin
// no one has requested before, req memory // no one has requested before, req memory
@@ -536,7 +536,7 @@ module mkL2Tlb(L2Tlb::L2Tlb);
fshow(vm_info), "; ", fshow(resp), "; ", fshow(vm_info), "; ", fshow(resp), "; ",
fshow(level), "; ", fshow(pteAddr)); fshow(level), "; ", fshow(pteAddr));
end end
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// perf: saved page walks // perf: saved page walks
if(doStats) begin if(doStats) begin
Data saved = zeroExtend(maxPageWalkLevel - level); Data saved = zeroExtend(maxPageWalkLevel - level);
@@ -545,9 +545,10 @@ module mkL2Tlb(L2Tlb::L2Tlb);
end end
else begin else begin
dataSavedPageWalks.incr(saved); dataSavedPageWalks.incr(saved);
$display("L2TlbdataSavedPageWalks = %0d", dataPageWalks);
end end
end end
`endif // `endif
endrule endrule
// page walk is preempted by tlb resp rule and trans cache resp rule, i.e., // page walk is preempted by tlb resp rule and trans cache resp rule, i.e.,
@@ -588,10 +589,10 @@ module mkL2Tlb(L2Tlb::L2Tlb);
// req is done // req is done
pendValid_pageWalk[idx] <= False; pendValid_pageWalk[idx] <= False;
pendWait_pageWalk[idx] <= None; pendWait_pageWalk[idx] <= None;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// incr miss latency // incr miss latency
incrMissLat(cRq.child, idx); incrMissLat(cRq.child, idx);
`endif // `endif
endaction endaction
endfunction endfunction
@@ -656,11 +657,11 @@ module mkL2Tlb(L2Tlb::L2Tlb);
// walk // walk
if(otherReqSamePTE(idx, newPTEAddr, readVReg(pendWait_pageWalk)) matches tagged Valid .i) begin if(otherReqSamePTE(idx, newPTEAddr, readVReg(pendWait_pageWalk)) matches tagged Valid .i) begin
pendWait_pageWalk[idx] <= WaitPeer (i); pendWait_pageWalk[idx] <= WaitPeer (i);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
peerSavedMemReqCnt.incr(1); peerSavedMemReqCnt.incr(1);
end end
`endif // `endif
end end
else begin else begin
memReqQ.enq(TlbMemReq { memReqQ.enq(TlbMemReq {
@@ -695,17 +696,17 @@ module mkL2Tlb(L2Tlb::L2Tlb);
child: cRq.child, child: cRq.child,
entry: Valid (entry) entry: Valid (entry)
}); });
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
// page table walks are counted as accesses // page table walks are counted as accesses
EventsLL ev = unpack(0); EventsLL ev = unpack(0);
ev.evt_TLB = 1; ev.evt_TLB = 1;
perf_events[1] <= ev; perf_events[1] <= ev;
`endif // `endif
// update TLB array // update TLB array
if(entry.level > 0) begin if(entry.level > 0) begin
// add to mega/giga page tlb // add to mega/giga page tlb
tlbMG.addEntry(entry); tlbMG.addEntry(entry);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
if(doStats) begin if(doStats) begin
if(cRq.child == I) begin if(cRq.child == I) begin
instHugePageMissCnt.incr(1); instHugePageMissCnt.incr(1);
@@ -714,12 +715,12 @@ module mkL2Tlb(L2Tlb::L2Tlb);
dataHugePageMissCnt.incr(1); dataHugePageMissCnt.incr(1);
end end
end end
`endif // `endif
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
EventsLL ev = unpack(0); EventsLL ev = unpack(0);
ev.evt_TLB_MISS = 1; ev.evt_TLB_MISS = 1;
perf_events[0] <= ev; perf_events[0] <= ev;
`endif // `endif
end end
else begin else begin
// 4KB page, add to 4KB TLB // 4KB page, add to 4KB TLB
@@ -728,13 +729,13 @@ module mkL2Tlb(L2Tlb::L2Tlb);
// req is done // req is done
pendValid_pageWalk[idx] <= False; pendValid_pageWalk[idx] <= False;
pendWait_pageWalk[idx] <= None; pendWait_pageWalk[idx] <= None;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// incr miss latency // incr miss latency
incrMissLat(cRq.child, idx); incrMissLat(cRq.child, idx);
`endif // `endif
end end
end end
`ifdef PERF_COUNT // `ifdef PERF_COUNT
// perf: page walk done once // perf: page walk done once
if(doStats) begin if(doStats) begin
if(cRq.child == I) begin if(cRq.child == I) begin
@@ -742,9 +743,10 @@ module mkL2Tlb(L2Tlb::L2Tlb);
end end
else begin else begin
dataPageWalks.incr(1); dataPageWalks.incr(1);
$display("L2TlbdataPageWalks = %0d", dataPageWalks);
end end
end end
`endif // `endif
endrule endrule
method Action updateVMInfo(VMInfo vmI, VMInfo vmD); //if(!isValid(pendReq)); method Action updateVMInfo(VMInfo vmI, VMInfo vmD); //if(!isValid(pendReq));
@@ -776,11 +778,11 @@ module mkL2Tlb(L2Tlb::L2Tlb);
interface Perf perf; interface Perf perf;
method Action setStatus(Bool stats); method Action setStatus(Bool stats);
`ifdef PERF_COUNT // `ifdef PERF_COUNT
doStats <= stats; doStats <= stats;
`else // `else
noAction; // noAction;
`endif // `endif
endmethod endmethod
method Action req(L2TlbPerfType r); method Action req(L2TlbPerfType r);
@@ -788,27 +790,27 @@ module mkL2Tlb(L2Tlb::L2Tlb);
endmethod endmethod
method ActionValue#(PerfResp#(L2TlbPerfType)) resp; method ActionValue#(PerfResp#(L2TlbPerfType)) resp;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
perfRespQ.deq; perfRespQ.deq;
return perfRespQ.first; return perfRespQ.first;
`else // `else
perfReqQ.deq; // perfReqQ.deq;
return PerfResp { // return PerfResp {
pType: perfReqQ.first, // pType: perfReqQ.first,
data: 0 // data: 0
}; // };
`endif // `endif
endmethod endmethod
method Bool respValid; method Bool respValid;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
return perfRespQ.notEmpty; return perfRespQ.notEmpty;
`else // `else
return perfReqQ.notEmpty; // return perfReqQ.notEmpty;
`endif // `endif
endmethod endmethod
endinterface endinterface
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsLL events = perf_events[0]; method EventsLL events = perf_events[0];
`endif // `endif
endmodule endmodule

View File

@@ -55,9 +55,9 @@ import SelfInvLLBank::*;
import L1CoCache::*; import L1CoCache::*;
import LLCDmaConnect::*; import LLCDmaConnect::*;
import Performance::*; import Performance::*;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
import StatCounters::*; import StatCounters::*;
`endif // `endif
// Last-Level // Last-Level
@@ -257,9 +257,9 @@ interface LLCache;
interface Get#(LLCStuck) cRqStuck; interface Get#(LLCStuck) cRqStuck;
// performance // performance
interface Perf#(LLCPerfType) perf; interface Perf#(LLCPerfType) perf;
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsLL events; method EventsLL events;
`endif // `endif
endinterface endinterface
`ifdef SECURITY `ifdef SECURITY
@@ -315,7 +315,7 @@ module mkLLCache(LLCache);
// perf counters // perf counters
Fifo#(1, LLCPerfType) perfReqQ <- mkCFFifo; Fifo#(1, LLCPerfType) perfReqQ <- mkCFFifo;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
Fifo#(1, PerfResp#(LLCPerfType)) perfRespQ <- mkCFFifo; Fifo#(1, PerfResp#(LLCPerfType)) perfRespQ <- mkCFFifo;
rule doPerf; rule doPerf;
@@ -326,7 +326,7 @@ module mkLLCache(LLCache);
data: d data: d
}); });
endrule endrule
`endif // `endif
`ifdef SECURITY `ifdef SECURITY
`ifndef DISABLE_SECURE_LLC `ifndef DISABLE_SECURE_LLC
@@ -449,26 +449,26 @@ module mkLLCache(LLCache);
perfReqQ.enq(r); perfReqQ.enq(r);
endmethod endmethod
method ActionValue#(PerfResp#(LLCPerfType)) resp; method ActionValue#(PerfResp#(LLCPerfType)) resp;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
perfRespQ.deq; perfRespQ.deq;
return perfRespQ.first; return perfRespQ.first;
`else // `else
perfReqQ.deq; // perfReqQ.deq;
return PerfResp { // return PerfResp {
pType: perfReqQ.first, // pType: perfReqQ.first,
data: 0 // data: 0
}; // };
`endif // `endif
endmethod endmethod
method Bool respValid; method Bool respValid;
`ifdef PERF_COUNT // `ifdef PERF_COUNT
return perfRespQ.notEmpty; return perfRespQ.notEmpty;
`else // `else
return perfReqQ.notEmpty; // return perfReqQ.notEmpty;
`endif // `endif
endmethod endmethod
endinterface endinterface
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
method EventsLL events = cache.events; method EventsLL events = cache.events;
`endif // `endif
endmodule endmodule

View File

@@ -1070,11 +1070,11 @@ endfunction
function x addPc(x cap, Bit#(12) inc) provisos (Add#(f, 12, c), CHERICap::CHERICap#(x, a, b, c, d, e)) = setAddrUnsafe(cap, getAddr(cap) + signExtend(inc)); function x addPc(x cap, Bit#(12) inc) provisos (Add#(f, 12, c), CHERICap::CHERICap#(x, a, b, c, d, e)) = setAddrUnsafe(cap, getAddr(cap) + signExtend(inc));
`ifdef PERFORMANCE_MONITORING // `ifdef PERFORMANCE_MONITORING
typedef 8 Report_Width; typedef 8 Report_Width;
typedef 64 Counter_Width; typedef 64 Counter_Width;
typedef 29 No_Of_Ctrs; typedef 29 No_Of_Ctrs;
`endif // `endif
function Bit#(outWidth) hash(Bit#(inWidth) in) function Bit#(outWidth) hash(Bit#(inWidth) in)
provisos(Add#(a__, inWidth, TMul#(TDiv#(inWidth, outWidth), outWidth)), provisos(Add#(a__, inWidth, TMul#(TDiv#(inWidth, outWidth), outWidth)),