Compare commits
8 Commits
master
...
master-per
| Author | SHA1 | Date | |
|---|---|---|---|
| 2227b084a1 | |||
| 263efec2a5 | |||
| 12ce7e7ade | |||
| b14264eb45 | |||
| 365a35e61b | |||
| 746dce577f | |||
| 0e8b7f38dc | |||
| af459956b7 |
3699
0001-enabled-performance-counters.patch
Normal file
3699
0001-enabled-performance-counters.patch
Normal file
File diff suppressed because it is too large
Load Diff
482
Tests/isa/Cprograms/benchmark/barnes/barnes_hut.c
Normal file
482
Tests/isa/Cprograms/benchmark/barnes/barnes_hut.c
Normal file
@@ -0,0 +1,482 @@
|
|||||||
|
/*
|
||||||
|
* File: barnes_hut.c
|
||||||
|
* --------------
|
||||||
|
* Implements the Barnes Hut algorithm for n-body
|
||||||
|
* simulation with galaxy-like initial conditions.
|
||||||
|
* Uses OpenGl and GLUT for graphics. Written by:
|
||||||
|
* Joel Backsell, Kim Torberntsson & Alexander Bilock.
|
||||||
|
* Source: https://github.com/KimTorberntsson/Barnes-Hut/blob/master/barnes_hut.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
// #include <time.h>
|
||||||
|
// #include <GLUT/glut.h>
|
||||||
|
|
||||||
|
#include "barnes_hut.h"
|
||||||
|
// #include "graphics.h"
|
||||||
|
|
||||||
|
void free(void *ptr);
|
||||||
|
void *malloc(size_t size);
|
||||||
|
|
||||||
|
//Some constants and global variables
|
||||||
|
int N = 10;
|
||||||
|
const double L = 1, W = 1, dt = 1e-3, alpha = 0.25, V = 50, epsilon = 1e-1, grav = 0.04; //grav should be 100/N
|
||||||
|
double *x, *y, *u, *v, *force_x, *force_y, *mass;
|
||||||
|
struct node_t *root;
|
||||||
|
|
||||||
|
// -------- Modified by Akilan ----------
|
||||||
|
|
||||||
|
double my_sqrt(double x) {
|
||||||
|
if (x <= 0) return 0;
|
||||||
|
|
||||||
|
double guess = x;
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
guess = 0.5 * (guess + x / guess);
|
||||||
|
}
|
||||||
|
return guess;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
double my_cos(double x) {
|
||||||
|
x = wrap_angle(x);
|
||||||
|
|
||||||
|
double x2 = x * x;
|
||||||
|
return 1
|
||||||
|
- x2 / 2
|
||||||
|
+ (x2 * x2) / 24
|
||||||
|
- (x2 * x2 * x2) / 720;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
|
||||||
|
// -------- Modified by Akilan ----------
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function for producing a random number between two double values
|
||||||
|
*/
|
||||||
|
double frand(double xmin, double xmax) {
|
||||||
|
return xmin + (xmax-xmin)*rand_test()/RAND_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prints the time between two clocks in seconds
|
||||||
|
*/
|
||||||
|
// void print_time(clock_t s, clock_t e)
|
||||||
|
// {
|
||||||
|
// printf("Time: %f seconds\n", (double)(e-s)/CLOCKS_PER_SEC);
|
||||||
|
// }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is called every time GLUT refreshes the display.
|
||||||
|
*/
|
||||||
|
// void display(void) {
|
||||||
|
// //Do a time step
|
||||||
|
// time_step();
|
||||||
|
|
||||||
|
// //Draw points
|
||||||
|
// drawPoints(x, y, N);
|
||||||
|
// }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Updates the positions of the particles of a time step.
|
||||||
|
*/
|
||||||
|
void time_step(void) {
|
||||||
|
//Allocate memory for root
|
||||||
|
root = malloc(sizeof(struct node_t));
|
||||||
|
set_node(root);
|
||||||
|
root->min_x = 0; root->max_x = 1; root->min_y = 0; root->max_y = 1;
|
||||||
|
|
||||||
|
//Put particles in tree
|
||||||
|
for(int i = 0; i < N; i++) {
|
||||||
|
put_particle_in_tree(i, root);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Calculate mass and center of mass
|
||||||
|
calculate_mass(root);
|
||||||
|
calculate_center_of_mass_x(root);
|
||||||
|
calculate_center_of_mass_y(root);
|
||||||
|
|
||||||
|
//Calculate forces
|
||||||
|
update_forces();
|
||||||
|
|
||||||
|
//Update velocities and positions
|
||||||
|
for(int i = 0; i < N; i++) {
|
||||||
|
double ax = force_x[i]/mass[i];
|
||||||
|
double ay = force_y[i]/mass[i];
|
||||||
|
u[i] += ax*dt;
|
||||||
|
v[i] += ay*dt;
|
||||||
|
x[i] += u[i]*dt;
|
||||||
|
y[i] += v[i]*dt;
|
||||||
|
|
||||||
|
/* This of course doesn't make any sense physically,
|
||||||
|
* but makes sure that the particles stay within the
|
||||||
|
* bounds. Normally the particles won't leave the
|
||||||
|
* area anyway.
|
||||||
|
*/
|
||||||
|
bounce(&x[i], &y[i], &u[i], &v[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Free memory
|
||||||
|
free_node(root);
|
||||||
|
free(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a particle moves beyond any of the boundaries then bounce it back
|
||||||
|
*/
|
||||||
|
void bounce(double *x, double *y, double *u, double *v) {
|
||||||
|
double W = 1.0f, H = 1.0f;
|
||||||
|
if(*x > W) {
|
||||||
|
*x = 2*W - *x;
|
||||||
|
*u = -*u;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*x < 0) {
|
||||||
|
*x = -*x;
|
||||||
|
*u = -*u;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*y > H) {
|
||||||
|
*y = 2*H - *y;
|
||||||
|
*v = -*v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*y < 0) {
|
||||||
|
*y = -*y;
|
||||||
|
*v = -*v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Puts a particle recursively in the Barnes Hut quad-tree.
|
||||||
|
*/
|
||||||
|
void put_particle_in_tree(int new_particle, struct node_t *node) {
|
||||||
|
//If no particle is assigned to the node
|
||||||
|
if(!node->has_particle) {
|
||||||
|
node->particle = new_particle;
|
||||||
|
node->has_particle = 1;
|
||||||
|
}
|
||||||
|
//If the node has no children
|
||||||
|
else if(!node->has_children) {
|
||||||
|
//Allocate and initiate children
|
||||||
|
node->children = malloc(4*sizeof(struct node_t));
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
set_node(&node->children[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set boundaries for the children
|
||||||
|
node->children[0].min_x = node->min_x; node->children[0].max_x = (node->min_x + node->max_x)/2;
|
||||||
|
node->children[0].min_y = node->min_y; node->children[0].max_y = (node->min_y + node->max_y)/2;
|
||||||
|
|
||||||
|
node->children[1].min_x = (node->min_x + node->max_x)/2; node->children[1].max_x = node->max_x;
|
||||||
|
node->children[1].min_y = node->min_y; node->children[1].max_y = (node->min_y + node->max_y)/2;
|
||||||
|
|
||||||
|
node->children[2].min_x = node->min_x; node->children[2].max_x = (node->min_x + node->max_x)/2;
|
||||||
|
node->children[2].min_y = (node->min_y + node->max_y)/2; node->children[2].max_y = node->max_y;
|
||||||
|
|
||||||
|
node->children[3].min_x = (node->min_x + node->max_x)/2; node->children[3].max_x = node->max_x;
|
||||||
|
node->children[3].min_y = (node->min_y + node->max_y)/2; node->children[3].max_y = node->max_y;
|
||||||
|
|
||||||
|
//Put old particle into the appropriate child
|
||||||
|
place_particle(node->particle, node);
|
||||||
|
|
||||||
|
//Put new particle into the appropriate child
|
||||||
|
place_particle(new_particle, node);
|
||||||
|
|
||||||
|
//It now has children
|
||||||
|
node->has_children = 1;
|
||||||
|
}
|
||||||
|
//Add the new particle to the appropriate children
|
||||||
|
else {
|
||||||
|
//Put new particle into the appropriate child
|
||||||
|
place_particle(new_particle, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Puts a particle in the right child of a node with children.
|
||||||
|
*/
|
||||||
|
void place_particle(int particle, struct node_t *node) {
|
||||||
|
if(x[particle] <= (node->min_x + node->max_x)/2 && y[particle] <= (node->min_y + node->max_y)/2) {
|
||||||
|
put_particle_in_tree(particle, &node->children[0]);
|
||||||
|
} else if(x[particle] > (node->min_x + node->max_x)/2 && y[particle] < (node->min_y + node->max_y)/2) {
|
||||||
|
put_particle_in_tree(particle, &node->children[1]);
|
||||||
|
} else if(x[particle] < (node->min_x + node->max_x)/2 && y[particle] > (node->min_y + node->max_y)/2) {
|
||||||
|
put_particle_in_tree(particle, &node->children[2]);
|
||||||
|
} else {
|
||||||
|
put_particle_in_tree(particle, &node->children[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets initial values for a new node
|
||||||
|
*/
|
||||||
|
void set_node(struct node_t *node) {
|
||||||
|
node->has_particle = 0;
|
||||||
|
node->has_children = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Frees memory for a node and its children recursively.
|
||||||
|
*/
|
||||||
|
void free_node(struct node_t *node){
|
||||||
|
if(node->has_children){
|
||||||
|
free_node(&node->children[0]);
|
||||||
|
free_node(&node->children[1]);
|
||||||
|
free_node(&node->children[2]);
|
||||||
|
free_node(&node->children[3]);
|
||||||
|
free(node->children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Displays the boundaries of the tree using OpenGL and GLUT.
|
||||||
|
* Used for debugging purposes.
|
||||||
|
*/
|
||||||
|
// void display_tree(struct node_t *node) {
|
||||||
|
// drawRect(node->min_x, node->max_x, node->min_y, node->max_y);
|
||||||
|
// if(node->has_children == 1) {
|
||||||
|
// for(int i = 0; i < 4; i++) {
|
||||||
|
// display_tree(&node->children[i]);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculates the total mass for the node. It recursively updates the mass
|
||||||
|
* of itself and all of its children.
|
||||||
|
*/
|
||||||
|
double calculate_mass(struct node_t *node) {
|
||||||
|
if(!node->has_particle) {
|
||||||
|
node->total_mass = 0;
|
||||||
|
} else if(!node->has_children) {
|
||||||
|
node->total_mass = mass[node->particle];
|
||||||
|
} else {
|
||||||
|
node->total_mass = 0;
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
node->total_mass += calculate_mass(&node->children[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node->total_mass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculates the x-position of the centre of mass for the
|
||||||
|
* node. It recursively updates the position of itself and
|
||||||
|
* all of its children.
|
||||||
|
*/
|
||||||
|
double calculate_center_of_mass_x(struct node_t *node) {
|
||||||
|
if(!node->has_children) {
|
||||||
|
node->c_x = x[node->particle];
|
||||||
|
} else {
|
||||||
|
node->c_x = 0;
|
||||||
|
double m_tot = 0;
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
if(node->children[i].has_particle) {
|
||||||
|
node->c_x += node->children[i].total_mass*calculate_center_of_mass_x(&node->children[i]);
|
||||||
|
m_tot += node->children[i].total_mass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node->c_x /= m_tot;
|
||||||
|
}
|
||||||
|
return node->c_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculates the y-position of the centre of mass for the
|
||||||
|
* node. It recursively updates the position of itself and
|
||||||
|
* all of its children.
|
||||||
|
*/
|
||||||
|
double calculate_center_of_mass_y(struct node_t *node) {
|
||||||
|
if(!node->has_children) {
|
||||||
|
node->c_y = y[node->particle];
|
||||||
|
} else {
|
||||||
|
node->c_y = 0;
|
||||||
|
double m_tot = 0;
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
if(node->children[i].has_particle) {
|
||||||
|
node->c_y += node->children[i].total_mass*calculate_center_of_mass_y(&node->children[i]);
|
||||||
|
m_tot += node->children[i].total_mass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node->c_y /= m_tot;
|
||||||
|
}
|
||||||
|
return node->c_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculates the forces in a time step of all particles in
|
||||||
|
* the simulation using the Barnes Hut quad tree.
|
||||||
|
*/
|
||||||
|
void update_forces(){
|
||||||
|
for(int i = 0; i < N; i++) {
|
||||||
|
force_x[i] = 0;
|
||||||
|
force_y[i] = 0;
|
||||||
|
update_forces_help(i, root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Help function for calculating the forces recursively
|
||||||
|
* using the Barnes Hut quad tree.
|
||||||
|
*/
|
||||||
|
void update_forces_help(int particle, struct node_t *node) {
|
||||||
|
//The node is a leaf node with a particle and not the particle itself
|
||||||
|
if(!node->has_children && node->has_particle && node->particle != particle) {
|
||||||
|
double r = my_sqrt((x[particle] - node->c_x)*(x[particle] - node->c_x) + (y[particle] - node->c_y)*(y[particle] - node->c_y));
|
||||||
|
calculate_force(particle, node, r);
|
||||||
|
}
|
||||||
|
//The node has children
|
||||||
|
else if(node->has_children) {
|
||||||
|
//Calculate r and theta
|
||||||
|
double r = my_sqrt((x[particle] - node->c_x)*(x[particle] - node->c_x) + (y[particle] - node->c_y)*(y[particle] - node->c_y));
|
||||||
|
double theta = (node->max_x - node->min_x)/r;
|
||||||
|
|
||||||
|
/* If the distance to the node's centre of mass is far enough, calculate the force,
|
||||||
|
* otherwise traverse further down the tree
|
||||||
|
*/
|
||||||
|
if(theta < 0.5){
|
||||||
|
calculate_force(particle, node, r);
|
||||||
|
} else {
|
||||||
|
update_forces_help(particle, &node->children[0]);
|
||||||
|
update_forces_help(particle, &node->children[1]);
|
||||||
|
update_forces_help(particle, &node->children[2]);
|
||||||
|
update_forces_help(particle, &node->children[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculates and updates the force of a particle from a node.
|
||||||
|
*/
|
||||||
|
void calculate_force(int particle, struct node_t *node, double r){
|
||||||
|
double temp = -grav*mass[particle]*node->total_mass/((r + epsilon)*(r + epsilon)*(r + epsilon));
|
||||||
|
force_x[particle] += (x[particle] - node->c_x)*temp;
|
||||||
|
force_y[particle] += (y[particle] - node->c_y)*temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main function.
|
||||||
|
*/
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
//The first arguments sets if the graphics should be used
|
||||||
|
// int graphics = 1;
|
||||||
|
// if (argc > 1) {
|
||||||
|
// graphics = atoi(argv[1]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//The second argument sets the number of time steps
|
||||||
|
int time_steps = 3;
|
||||||
|
// if (argc > 2) {
|
||||||
|
// time_steps = atoi(argv[2]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//Initiate memory for the vectors
|
||||||
|
x = (double *)malloc(N*sizeof(double));
|
||||||
|
y = (double *)malloc(N*sizeof(double));
|
||||||
|
u = (double *)malloc(N*sizeof(double));
|
||||||
|
v = (double *)malloc(N*sizeof(double));
|
||||||
|
// -------- Modified by Akilan ----------
|
||||||
|
force_x = (double *)malloc(N*sizeof(double));
|
||||||
|
force_y = (double *)malloc(N*sizeof(double));
|
||||||
|
// --------------------------------------
|
||||||
|
mass = (double *)malloc(N*sizeof(double));
|
||||||
|
|
||||||
|
//Set the initial values
|
||||||
|
// for(int i = 0; i < N; i++) {
|
||||||
|
// mass[i] = 1;
|
||||||
|
// double R = frand(0, L/4);
|
||||||
|
// double theta = frand(0, 2*M_PI);
|
||||||
|
// x[i] = L/2 + R*my_cos(theta);
|
||||||
|
// y[i] = W/2 + alpha*R*my_sin(theta);
|
||||||
|
// double R_prim = my_sqrt(pow(x[i] - L/2, 2) + pow(y[i] - W/2, 2));
|
||||||
|
// u[i] = -V*R_prim*my_sin(theta);
|
||||||
|
// v[i] = V*R_prim*my_cos(theta);
|
||||||
|
// }
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
mass[i] = 1;
|
||||||
|
|
||||||
|
double R = frand(0, L/4);
|
||||||
|
double theta = frand(0, 2*PI);
|
||||||
|
|
||||||
|
double c = my_cos(theta);
|
||||||
|
double s = my_sin(theta);
|
||||||
|
|
||||||
|
x[i] = L/2 + R * c;
|
||||||
|
y[i] = W/2 + alpha * R * s;
|
||||||
|
|
||||||
|
double dx = x[i] - L/2;
|
||||||
|
double dy = y[i] - W/2;
|
||||||
|
|
||||||
|
double R_prim = my_sqrt(dx*dx + dy*dy);
|
||||||
|
|
||||||
|
u[i] = -V * R_prim * s;
|
||||||
|
v[i] = V * R_prim * c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run the GLUT display function if the graphics mode is on.
|
||||||
|
* Otherwise just run the simulations without graphics
|
||||||
|
*/
|
||||||
|
// if (graphics) {
|
||||||
|
// // Initialize the graphics routines
|
||||||
|
// graphicsInit(&argc, argv, display);
|
||||||
|
|
||||||
|
// //Used for the display window
|
||||||
|
// glutMainLoop();
|
||||||
|
// } else {
|
||||||
|
//Begin taking time
|
||||||
|
// long start = clock();
|
||||||
|
|
||||||
|
//The main loop
|
||||||
|
for(int i = 0; i < time_steps; i++) {
|
||||||
|
time_step();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Stop taking time and print elapsed time
|
||||||
|
// long stop = clock();
|
||||||
|
// print_time(start, stop);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//Free memory
|
||||||
|
free(x);
|
||||||
|
free(y);
|
||||||
|
free(u);
|
||||||
|
free(v);
|
||||||
|
free(force_x);
|
||||||
|
free(force_y);
|
||||||
|
free(mass);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
55
Tests/isa/Cprograms/benchmark/barnes/barnes_hut.h
Normal file
55
Tests/isa/Cprograms/benchmark/barnes/barnes_hut.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* File: barnes_hut.h
|
||||||
|
* --------------
|
||||||
|
* Header file for barnes_hut.c
|
||||||
|
* Written by:
|
||||||
|
* Joel Backsell, Kim Torberntsson & Alexander Bilock.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Barnes_Hut_barnes_hut_h
|
||||||
|
#define Barnes_Hut_barnes_hut_h
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Struct that represents a node of the Barnes Hut quad tree.
|
||||||
|
*/
|
||||||
|
struct node_t {
|
||||||
|
int particle;
|
||||||
|
int has_particle;
|
||||||
|
int has_children;
|
||||||
|
double min_x, max_x, min_y, max_y, total_mass, c_x, c_y;
|
||||||
|
struct node_t *children;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Function for producing a random number between two double values.
|
||||||
|
double frand(double xmin, double xmax);
|
||||||
|
|
||||||
|
//Prints the time between two clocks in seconds
|
||||||
|
// void print_time(clock_t s, clock_t e);
|
||||||
|
|
||||||
|
//OpenGL method for displaying the particles
|
||||||
|
// void display(void);
|
||||||
|
|
||||||
|
//Calculates the positions of a time step
|
||||||
|
// void time_step(void);
|
||||||
|
|
||||||
|
//If a particle moves beyond any of the boundaries then bounce it back
|
||||||
|
void bounce(double *x, double *y, double *u, double *v);
|
||||||
|
|
||||||
|
//Functions for handling the placement of particles in the tree
|
||||||
|
void put_particle_in_tree(int new_particle, struct node_t *node);
|
||||||
|
void place_particle(int particle, struct node_t *node);
|
||||||
|
void set_node(struct node_t *node);
|
||||||
|
void free_node(struct node_t *node);
|
||||||
|
void display_tree(struct node_t *node);
|
||||||
|
|
||||||
|
//Functions for calculating the mass and centre of mass of the tree
|
||||||
|
double calculate_mass(struct node_t *node);
|
||||||
|
double calculate_center_of_mass_x(struct node_t *node);
|
||||||
|
double calculate_center_of_mass_y(struct node_t *node);
|
||||||
|
|
||||||
|
//Functions for the force calculations
|
||||||
|
void update_forces();
|
||||||
|
void update_forces_help(int particle, struct node_t *node);
|
||||||
|
void calculate_force(int particle, struct node_t *node, double r);
|
||||||
|
|
||||||
|
#endif
|
||||||
46
Tests/isa/Cprograms/benchmark/barnes/build.sh
Normal file
46
Tests/isa/Cprograms/benchmark/barnes/build.sh
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# scp ../../encoding.h home-1:/home/akilan/
|
||||||
|
# scp ../../entry.S home-1:/home/akilan/
|
||||||
|
# scp ../../link.ld home-1:/home/akilan/
|
||||||
|
# scp ../../riscv_test_p.h home-1:/home/akilan/
|
||||||
|
# scp ../../riscv_test.h home-1:/home/akilan/
|
||||||
|
# scp ../../string.c home-1:/home/akilan/
|
||||||
|
# scp ../../vm.c home-1:/home/akilan/
|
||||||
|
# scp ../../test.S home-1:/home/akilan/
|
||||||
|
# scp ../../test_macros.h home-1:/home/akilan/
|
||||||
|
# scp ../../malloc.c home-1:/home/akilan/
|
||||||
|
# scp ../../test.c home-1:/home/akilan/
|
||||||
|
scp barnes_hut.c home-1:/home/akilan/
|
||||||
|
scp barnes_hut.h home-1:/home/akilan/
|
||||||
|
|
||||||
|
# GCC compile
|
||||||
|
# ssh home-1 'cd /home/akilan/ && export PATH=/opt/riscv/bin:$PATH && riscv64-unknown-elf-gcc -DENTROPY=0xf21e02b -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -mabi=lp64 -T link.ld vm.c string.c entry.S test.S -o testC'
|
||||||
|
|
||||||
|
# Clang compile (architecture Regular RISCV)
|
||||||
|
ssh home-1 'clang --target=riscv64-unknown-elf -DENTROPY=0xf21e02b -DDEFINE_MALLOC -DDEFINE_FREE --gcc-toolchain=/opt/riscv -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -fno-builtin-malloc -mabi=lp64 -T link.ld vm.c string.c malloc.c entry.S test.S barnes_hut.c -o testC -lm -lgcc'
|
||||||
|
|
||||||
|
# Clang using the cheri clang compiler
|
||||||
|
# ssh home-1 'cd cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-freebsd -DENTROPY=0xf21e02b --sysroot=cheribsd-riscv64-for-purecap-rootfs.cfg -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -march=rv64imafdcxcheri -mabi=lp64d -T link.ld vm.c string.c entry.S test.S -o testC'
|
||||||
|
|
||||||
|
scp home-1:/home/akilan/testC ../../../
|
||||||
|
|
||||||
|
# scp home-1:/home/akilan/cheri/output/sdk/bin/testC .
|
||||||
|
|
||||||
|
# riscv64-unknown-elf-gcc \
|
||||||
|
# -march=rv64imac \
|
||||||
|
# -mabi=lp64 \
|
||||||
|
# -nostartfiles \
|
||||||
|
# -fno-builtin \
|
||||||
|
# -T link.ld \
|
||||||
|
# entry.S vm.c string.c \
|
||||||
|
|
||||||
|
# clang \
|
||||||
|
# --target=riscv64-unknown-elf \
|
||||||
|
# -march=rv64imac \
|
||||||
|
# -mabi=lp64 \
|
||||||
|
# -nostdlib \
|
||||||
|
# -nostartfiles \
|
||||||
|
# -fuse-ld=lld \
|
||||||
|
# -T link.ld \
|
||||||
|
# entry.S vm.c string.c \
|
||||||
|
# -I. \
|
||||||
|
# -o output.elf%
|
||||||
45
Tests/isa/Cprograms/benchmark/glibc/build.sh
Normal file
45
Tests/isa/Cprograms/benchmark/glibc/build.sh
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
scp ../../encoding.h home-1:/home/akilan/
|
||||||
|
scp ../../entry.S home-1:/home/akilan/
|
||||||
|
scp ../../link.ld home-1:/home/akilan/
|
||||||
|
scp ../../riscv_test_p.h home-1:/home/akilan/
|
||||||
|
scp ../../riscv_test.h home-1:/home/akilan/
|
||||||
|
scp ../../string.c home-1:/home/akilan/
|
||||||
|
scp ../../vm.c home-1:/home/akilan/
|
||||||
|
scp ../../test.S home-1:/home/akilan/
|
||||||
|
scp ../../test_macros.h home-1:/home/akilan/
|
||||||
|
scp ../../malloc.c home-1:/home/akilan/
|
||||||
|
# scp ../../test.c home-1:/home/akilan/
|
||||||
|
scp glibc.c home-1:/home/akilan/
|
||||||
|
|
||||||
|
# GCC compile
|
||||||
|
# ssh home-1 'cd /home/akilan/ && export PATH=/opt/riscv/bin:$PATH && riscv64-unknown-elf-gcc -DENTROPY=0xf21e02b -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -mabi=lp64 -T link.ld vm.c string.c entry.S test.S -o testC'
|
||||||
|
|
||||||
|
# Clang compile (architecture Regular RISCV)
|
||||||
|
ssh home-1 'clang --target=riscv64-unknown-elf -DENTROPY=0xf21e02b -DDEFINE_MALLOC -DDEFINE_FREE --gcc-toolchain=/opt/riscv -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -fno-builtin-malloc -mabi=lp64 -T link.ld vm.c string.c malloc.c entry.S test.S glibc.c -o testC'
|
||||||
|
|
||||||
|
# Clang using the cheri clang compiler
|
||||||
|
# ssh home-1 'cd cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-freebsd -DENTROPY=0xf21e02b --sysroot=cheribsd-riscv64-for-purecap-rootfs.cfg -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -march=rv64imafdcxcheri -mabi=lp64d -T link.ld vm.c string.c entry.S test.S -o testC'
|
||||||
|
|
||||||
|
scp home-1:/home/akilan/testC ../../../
|
||||||
|
|
||||||
|
# scp home-1:/home/akilan/cheri/output/sdk/bin/testC .
|
||||||
|
|
||||||
|
# riscv64-unknown-elf-gcc \
|
||||||
|
# -march=rv64imac \
|
||||||
|
# -mabi=lp64 \
|
||||||
|
# -nostartfiles \
|
||||||
|
# -fno-builtin \
|
||||||
|
# -T link.ld \
|
||||||
|
# entry.S vm.c string.c \
|
||||||
|
|
||||||
|
# clang \
|
||||||
|
# --target=riscv64-unknown-elf \
|
||||||
|
# -march=rv64imac \
|
||||||
|
# -mabi=lp64 \
|
||||||
|
# -nostdlib \
|
||||||
|
# -nostartfiles \
|
||||||
|
# -fuse-ld=lld \
|
||||||
|
# -T link.ld \
|
||||||
|
# entry.S vm.c string.c \
|
||||||
|
# -I. \
|
||||||
|
# -o output.elf%
|
||||||
229
Tests/isa/Cprograms/benchmark/glibc/glibc.c
Normal file
229
Tests/isa/Cprograms/benchmark/glibc/glibc.c
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
/* Benchmark malloc and free functions.
|
||||||
|
Copyright (C) 2019-2021 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
// modified by Daan Leijen to fit the bench suite and add lifo/fifo free order.
|
||||||
|
|
||||||
|
// #include <pthread.h>
|
||||||
|
// #include <stdio.h>
|
||||||
|
// #include <stdlib.h>
|
||||||
|
// #include <sys/resource.h>
|
||||||
|
// #include "malloc.h"
|
||||||
|
|
||||||
|
// #include <cheriintrin.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// #define malloc MALLOCCHERI
|
||||||
|
// #define free FREECHERI
|
||||||
|
|
||||||
|
// #include "bench-timing.h"
|
||||||
|
// #include "json-lib.h"
|
||||||
|
|
||||||
|
// void free(void * __capability ptr);
|
||||||
|
// void * __capability malloc(size_t size);
|
||||||
|
|
||||||
|
void* malloc(size_t size);
|
||||||
|
void free(void *ptr);
|
||||||
|
|
||||||
|
/* Benchmark the malloc/free performance of a varying number of blocks of a
|
||||||
|
given size. This enables performance tracking of the t-cache and fastbins.
|
||||||
|
It tests 3 different scenarios: single-threaded using main arena,
|
||||||
|
multi-threaded using thread-arena, and main arena with SINGLE_THREAD_P
|
||||||
|
false. */
|
||||||
|
|
||||||
|
// source: https://github.com/daanx/mimalloc-bench/blob/master/bench/glibc-bench/bench-malloc-thread.c
|
||||||
|
|
||||||
|
#define NUM_ITERS 20
|
||||||
|
#define NUM_ALLOCS 4
|
||||||
|
#define MAX_ALLOCS 1600
|
||||||
|
|
||||||
|
// Daan: disable timing
|
||||||
|
typedef long timing_t;
|
||||||
|
#define TIMING_NOW(s)
|
||||||
|
#define TIMING_DIFF(e,start,stop)
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
size_t iters;
|
||||||
|
size_t size;
|
||||||
|
int n;
|
||||||
|
timing_t elapsed;
|
||||||
|
} malloc_args;
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_benchmark(malloc_args *args, char **arr)
|
||||||
|
{
|
||||||
|
// timing_t start, stop;
|
||||||
|
size_t iters = args->iters;
|
||||||
|
size_t size = args->size;
|
||||||
|
int n = args->n;
|
||||||
|
|
||||||
|
// TIMING_NOW (start);
|
||||||
|
|
||||||
|
for (int j = 0; j < iters; j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
arr[i] = malloc (size);
|
||||||
|
for(int g = 0; g < size; g++) { arr[i][g] =(char)g; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// free half in fifo order
|
||||||
|
for (int i = 0; i < n/2; i++) {
|
||||||
|
free (arr[i]);
|
||||||
|
arr[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// and the other half in lifo order
|
||||||
|
for(int i = n-1; i >= n/2; i--) {
|
||||||
|
free(arr[i]);
|
||||||
|
arr[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TIMING_NOW (stop);
|
||||||
|
|
||||||
|
// TIMING_DIFF (args->elapsed, start, stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
static malloc_args tests[3][NUM_ALLOCS];
|
||||||
|
static int allocs[NUM_ALLOCS] = { 25, 100, 400, MAX_ALLOCS };
|
||||||
|
|
||||||
|
// static void *
|
||||||
|
// thread_test (void *p)
|
||||||
|
// {
|
||||||
|
// char **arr = (char**)p;
|
||||||
|
|
||||||
|
// /* Run benchmark multi-threaded. */
|
||||||
|
// for (int i = 0; i < NUM_ALLOCS; i++)
|
||||||
|
// do_benchmark (&tests[2][i], arr);
|
||||||
|
|
||||||
|
// return p;
|
||||||
|
// }
|
||||||
|
|
||||||
|
void
|
||||||
|
bench (unsigned long size)
|
||||||
|
{
|
||||||
|
size_t iters = NUM_ITERS;
|
||||||
|
char**arr = (char**)malloc (MAX_ALLOCS * sizeof (void*));
|
||||||
|
//char * __capability * __capability arr = malloc(MAX_ALLOCS * sizeof(char * __capability));
|
||||||
|
|
||||||
|
for (int t = 0; t < 3; t++)
|
||||||
|
for (int i = 0; i < NUM_ALLOCS; i++)
|
||||||
|
{
|
||||||
|
tests[t][i].n = allocs[i];
|
||||||
|
tests[t][i].size = size;
|
||||||
|
tests[t][i].iters = iters / allocs[i];
|
||||||
|
|
||||||
|
/* Do a quick warmup run. */
|
||||||
|
if (t == 0)
|
||||||
|
do_benchmark (&tests[0][i], arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run benchmark single threaded in main_arena. */
|
||||||
|
for (int i = 0; i < NUM_ALLOCS; i++)
|
||||||
|
do_benchmark (&tests[0][i], arr);
|
||||||
|
|
||||||
|
/* Run benchmark in a thread_arena. */
|
||||||
|
// pthread_t t;
|
||||||
|
// pthread_create (&t, NULL, thread_test, (void*)arr);
|
||||||
|
// pthread_join (t, NULL);
|
||||||
|
|
||||||
|
/* Repeat benchmark in main_arena with SINGLE_THREAD_P == false. */
|
||||||
|
// for (int i = 0; i < NUM_ALLOCS; i++)
|
||||||
|
// do_benchmark (&tests[1][i], arr);
|
||||||
|
|
||||||
|
free (arr);
|
||||||
|
arr = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
json_ctx_t json_ctx;
|
||||||
|
|
||||||
|
json_init (&json_ctx, 0, stdout);
|
||||||
|
|
||||||
|
json_document_begin (&json_ctx);
|
||||||
|
|
||||||
|
json_attr_string (&json_ctx, "timing_type", TIMING_TYPE);
|
||||||
|
|
||||||
|
json_attr_object_begin (&json_ctx, "functions");
|
||||||
|
|
||||||
|
json_attr_object_begin (&json_ctx, "malloc");
|
||||||
|
|
||||||
|
char s[100];
|
||||||
|
double iters2 = iters;
|
||||||
|
|
||||||
|
json_attr_object_begin (&json_ctx, "");
|
||||||
|
json_attr_double (&json_ctx, "malloc_block_size", size);
|
||||||
|
|
||||||
|
struct rusage usage;
|
||||||
|
getrusage (RUSAGE_SELF, &usage);
|
||||||
|
json_attr_double (&json_ctx, "max_rss", usage.ru_maxrss);
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_ALLOCS; i++)
|
||||||
|
{
|
||||||
|
sprintf (s, "main_arena_st_allocs_%04d_time", allocs[i]);
|
||||||
|
json_attr_double (&json_ctx, s, tests[0][i].elapsed / iters2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_ALLOCS; i++)
|
||||||
|
{
|
||||||
|
sprintf (s, "main_arena_mt_allocs_%04d_time", allocs[i]);
|
||||||
|
json_attr_double (&json_ctx, s, tests[1][i].elapsed / iters2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_ALLOCS; i++)
|
||||||
|
{
|
||||||
|
sprintf (s, "thread_arena__allocs_%04d_time", allocs[i]);
|
||||||
|
json_attr_double (&json_ctx, s, tests[2][i].elapsed / iters2);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_attr_object_end (&json_ctx);
|
||||||
|
|
||||||
|
json_attr_object_end (&json_ctx);
|
||||||
|
|
||||||
|
json_attr_object_end (&json_ctx);
|
||||||
|
|
||||||
|
json_document_end (&json_ctx);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// static void usage (const char *name)
|
||||||
|
// {
|
||||||
|
// fprintf (stderr, "%s: <alloc_size>\n", name);
|
||||||
|
// exit (1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
// INITREGULARALLOC();
|
||||||
|
long size = 3;
|
||||||
|
// if (argc == 2)
|
||||||
|
// size = strtol (argv[1], NULL, 0);
|
||||||
|
|
||||||
|
// if (argc > 2 || size <= 0)
|
||||||
|
// usage (argv[0]);
|
||||||
|
|
||||||
|
bench (size);
|
||||||
|
// bench (2*size);
|
||||||
|
// bench (4*size);
|
||||||
|
// bench (8*size);
|
||||||
|
// bench (16*size);
|
||||||
|
// bench (32*size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
45
Tests/isa/Cprograms/benchmark/matrixmul/build.sh
Normal file
45
Tests/isa/Cprograms/benchmark/matrixmul/build.sh
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
scp ../../encoding.h home-1:/home/akilan/
|
||||||
|
scp ../../entry.S home-1:/home/akilan/
|
||||||
|
scp ../../link.ld home-1:/home/akilan/
|
||||||
|
scp ../../riscv_test_p.h home-1:/home/akilan/
|
||||||
|
scp ../../riscv_test.h home-1:/home/akilan/
|
||||||
|
scp ../../string.c home-1:/home/akilan/
|
||||||
|
scp ../../vm.c home-1:/home/akilan/
|
||||||
|
scp ../../test.S home-1:/home/akilan/
|
||||||
|
scp ../../test_macros.h home-1:/home/akilan/
|
||||||
|
scp ../../malloc.c home-1:/home/akilan/
|
||||||
|
# scp ../../test.c home-1:/home/akilan/
|
||||||
|
scp matrixmul.c home-1:/home/akilan/
|
||||||
|
|
||||||
|
# GCC compile
|
||||||
|
# ssh home-1 'cd /home/akilan/ && export PATH=/opt/riscv/bin:$PATH && riscv64-unknown-elf-gcc -DENTROPY=0xf21e02b -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -mabi=lp64 -T link.ld vm.c string.c entry.S test.S -o testC'
|
||||||
|
|
||||||
|
# Clang compile (architecture Regular RISCV)
|
||||||
|
ssh home-1 'clang --target=riscv64-unknown-elf -DENTROPY=0xf21e02b -DDEFINE_MALLOC -DDEFINE_FREE --gcc-toolchain=/opt/riscv -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -fno-builtin-malloc -mabi=lp64 -T link.ld vm.c string.c malloc.c entry.S test.S matrixmul.c -o testC'
|
||||||
|
|
||||||
|
# Clang using the cheri clang compiler
|
||||||
|
# ssh home-1 'cd cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-freebsd -DENTROPY=0xf21e02b --sysroot=cheribsd-riscv64-for-purecap-rootfs.cfg -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -march=rv64imafdcxcheri -mabi=lp64d -T link.ld vm.c string.c entry.S test.S -o testC'
|
||||||
|
|
||||||
|
scp home-1:/home/akilan/testC ../../../
|
||||||
|
|
||||||
|
# scp home-1:/home/akilan/cheri/output/sdk/bin/testC .
|
||||||
|
|
||||||
|
# riscv64-unknown-elf-gcc \
|
||||||
|
# -march=rv64imac \
|
||||||
|
# -mabi=lp64 \
|
||||||
|
# -nostartfiles \
|
||||||
|
# -fno-builtin \
|
||||||
|
# -T link.ld \
|
||||||
|
# entry.S vm.c string.c \
|
||||||
|
|
||||||
|
# clang \
|
||||||
|
# --target=riscv64-unknown-elf \
|
||||||
|
# -march=rv64imac \
|
||||||
|
# -mabi=lp64 \
|
||||||
|
# -nostdlib \
|
||||||
|
# -nostartfiles \
|
||||||
|
# -fuse-ld=lld \
|
||||||
|
# -T link.ld \
|
||||||
|
# entry.S vm.c string.c \
|
||||||
|
# -I. \
|
||||||
|
# -o output.elf%
|
||||||
205
Tests/isa/Cprograms/benchmark/matrixmul/matrixmul.c
Normal file
205
Tests/isa/Cprograms/benchmark/matrixmul/matrixmul.c
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
// 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>
|
||||||
|
|
||||||
|
void free(void *ptr);
|
||||||
|
void *malloc(size_t size);
|
||||||
|
|
||||||
|
/* Initializes vector or matrix, sequentially, with indices. */
|
||||||
|
void init_seq(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] = 2.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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. */
|
||||||
|
double *transpose(const double *m, const unsigned n_rows_m, const unsigned n_cols_m, double *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. */
|
||||||
|
double *dot_simple(const double *a, const unsigned n_rows_a, const unsigned n_cols_a,\
|
||||||
|
const double *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);
|
||||||
|
}
|
||||||
|
|
||||||
|
double *c = malloc(n_rows_a * n_cols_b * sizeof(*c));
|
||||||
|
if (c == NULL) {
|
||||||
|
// printf("Couldn't allocate memory!\n");
|
||||||
|
// system("pause");
|
||||||
|
// exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < n_rows_a; i++) {
|
||||||
|
for (size_t k = 0; k < n_cols_b; k++) {
|
||||||
|
double sum = 0.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. */
|
||||||
|
double *dot(const double *a, const unsigned n_rows_a, const unsigned n_cols_a, \
|
||||||
|
const double *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);
|
||||||
|
}
|
||||||
|
|
||||||
|
double *bt = malloc(n_rows_b * n_cols_b * sizeof(*b));
|
||||||
|
|
||||||
|
double *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++) {
|
||||||
|
double sum = 0.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 */
|
||||||
|
double t0, t1;
|
||||||
|
|
||||||
|
const unsigned scale = 2;
|
||||||
|
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;
|
||||||
|
|
||||||
|
double *a = malloc(n_rows_a * n_cols_a * sizeof(*a));
|
||||||
|
double *b = malloc(n_rows_b * n_cols_b * sizeof(*b));
|
||||||
|
double *c = NULL;
|
||||||
|
double *d = NULL;
|
||||||
|
|
||||||
|
if (!a || !b) {
|
||||||
|
// printf("Couldn't allocate memory!\n");
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// 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
|
||||||
45
Tests/isa/Cprograms/benchmark/memaccess/build.sh
Normal file
45
Tests/isa/Cprograms/benchmark/memaccess/build.sh
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
scp ../../encoding.h home-1:/home/akilan/
|
||||||
|
scp ../../entry.S home-1:/home/akilan/
|
||||||
|
scp ../../link.ld home-1:/home/akilan/
|
||||||
|
scp ../../riscv_test_p.h home-1:/home/akilan/
|
||||||
|
scp ../../riscv_test.h home-1:/home/akilan/
|
||||||
|
scp ../../string.c home-1:/home/akilan/
|
||||||
|
scp ../../vm.c home-1:/home/akilan/
|
||||||
|
scp ../../test.S home-1:/home/akilan/
|
||||||
|
scp ../../test_macros.h home-1:/home/akilan/
|
||||||
|
scp ../../malloc.c home-1:/home/akilan/
|
||||||
|
# scp ../../test.c home-1:/home/akilan/
|
||||||
|
scp memaccess.c home-1:/home/akilan/
|
||||||
|
|
||||||
|
# GCC compile
|
||||||
|
# ssh home-1 'cd /home/akilan/ && export PATH=/opt/riscv/bin:$PATH && riscv64-unknown-elf-gcc -DENTROPY=0xf21e02b -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -mabi=lp64 -T link.ld vm.c string.c entry.S test.S -o testC'
|
||||||
|
|
||||||
|
# Clang compile (architecture Regular RISCV)
|
||||||
|
ssh home-1 'clang --target=riscv64-unknown-elf -DENTROPY=0xf21e02b -DDEFINE_MALLOC -DDEFINE_FREE --gcc-toolchain=/opt/riscv -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -fno-builtin-malloc -mabi=lp64 -T link.ld vm.c string.c malloc.c entry.S test.S memaccess.c -o testC'
|
||||||
|
|
||||||
|
# Clang using the cheri clang compiler
|
||||||
|
# ssh home-1 'cd cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-freebsd -DENTROPY=0xf21e02b --sysroot=cheribsd-riscv64-for-purecap-rootfs.cfg -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -march=rv64imafdcxcheri -mabi=lp64d -T link.ld vm.c string.c entry.S test.S -o testC'
|
||||||
|
|
||||||
|
scp home-1:/home/akilan/testC ../../../
|
||||||
|
|
||||||
|
# scp home-1:/home/akilan/cheri/output/sdk/bin/testC .
|
||||||
|
|
||||||
|
# riscv64-unknown-elf-gcc \
|
||||||
|
# -march=rv64imac \
|
||||||
|
# -mabi=lp64 \
|
||||||
|
# -nostartfiles \
|
||||||
|
# -fno-builtin \
|
||||||
|
# -T link.ld \
|
||||||
|
# entry.S vm.c string.c \
|
||||||
|
|
||||||
|
# clang \
|
||||||
|
# --target=riscv64-unknown-elf \
|
||||||
|
# -march=rv64imac \
|
||||||
|
# -mabi=lp64 \
|
||||||
|
# -nostdlib \
|
||||||
|
# -nostartfiles \
|
||||||
|
# -fuse-ld=lld \
|
||||||
|
# -T link.ld \
|
||||||
|
# entry.S vm.c string.c \
|
||||||
|
# -I. \
|
||||||
|
# -o output.elf%
|
||||||
364
Tests/isa/Cprograms/benchmark/memaccess/memaccess.c
Normal file
364
Tests/isa/Cprograms/benchmark/memaccess/memaccess.c
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
/*
|
||||||
|
memaccesstest.c
|
||||||
|
Author Alex Bordei at bigstep
|
||||||
|
All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// source: https://github.com/bigstepinc/memaccesstest/tree/master
|
||||||
|
|
||||||
|
// #include <stdio.h>
|
||||||
|
// #include <cheriintrin.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
// #include <stdlib.h>
|
||||||
|
// #include <pthread.h>
|
||||||
|
// #include "config.h"
|
||||||
|
|
||||||
|
// #ifndef __MACH__
|
||||||
|
// #include <time.h>
|
||||||
|
// #else
|
||||||
|
// #include <mach/mach_time.h>
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #include "malloc.h"
|
||||||
|
|
||||||
|
// #define malloc MALLOCCHERI
|
||||||
|
// #define free FREECHERI
|
||||||
|
|
||||||
|
#define NPAD 7
|
||||||
|
#define MIN_WSS sizeof(struct l)
|
||||||
|
#define MAX_WSS 32
|
||||||
|
|
||||||
|
void free(void *ptr);
|
||||||
|
void *malloc(size_t size);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// struct l{
|
||||||
|
// struct l *n;
|
||||||
|
// struct l *p;
|
||||||
|
// long int pad[NPAD-1];
|
||||||
|
|
||||||
|
// };
|
||||||
|
|
||||||
|
struct l{
|
||||||
|
struct l *n;
|
||||||
|
struct l *p;
|
||||||
|
long int pad[NPAD-1];
|
||||||
|
};
|
||||||
|
|
||||||
|
// uint64_t rand64()
|
||||||
|
// {
|
||||||
|
// // Combin 4 parts of low 16-bit of each rand()
|
||||||
|
// uint64_t R0 = (uint64_t)random() << 48;
|
||||||
|
// uint64_t R1 = (uint64_t)random() << 48 >> 16;
|
||||||
|
// uint64_t R2 = (uint64_t)random() << 48 >> 32;
|
||||||
|
// uint64_t R3 = (uint64_t)random() << 48 >> 48;
|
||||||
|
// return R0 | R1 | R2 | R3;
|
||||||
|
// };
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
// void print_ll_lin(struct l *root,unsigned long working_set_size)
|
||||||
|
// {
|
||||||
|
// struct l *current=root->n;
|
||||||
|
// unsigned long count;
|
||||||
|
// printf("0");
|
||||||
|
// count=0;
|
||||||
|
// while(current!=root)
|
||||||
|
// {
|
||||||
|
// // printf("->%ld",current-root);
|
||||||
|
// current=current->n;
|
||||||
|
// count++;
|
||||||
|
// if(count>working_set_size/sizeof(struct l))
|
||||||
|
// {
|
||||||
|
// // printf("Error:cycle!");
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
// // printf("\n");
|
||||||
|
// }
|
||||||
|
// void print_ll_lin_back(struct l *root,unsigned long working_set_size)
|
||||||
|
// {
|
||||||
|
// struct l *current=root->p;
|
||||||
|
// unsigned long count;
|
||||||
|
// printf("0");
|
||||||
|
// count=0;
|
||||||
|
// while(current!=root)
|
||||||
|
// {
|
||||||
|
// // printf("->%ld",current-root);
|
||||||
|
// current=current->p;
|
||||||
|
// count++;
|
||||||
|
// if(count>working_set_size/sizeof(struct l))
|
||||||
|
// {
|
||||||
|
// // printf("Error:cycle!");
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
// printf("\n");
|
||||||
|
// }
|
||||||
|
// void print_ll(struct l *root,unsigned long working_set_size)
|
||||||
|
// {
|
||||||
|
// unsigned long i;
|
||||||
|
// for(i=0;i<(working_set_size/sizeof(struct l));i++)
|
||||||
|
// printf("DEBUG: %ld<-%ld->%ld\n",(root+i)->p-root,i,((root+i)->n)-root);
|
||||||
|
// printf("DEBUG ");
|
||||||
|
// print_ll_lin(root, working_set_size);
|
||||||
|
// printf("DEBUG ");
|
||||||
|
// print_ll_lin_back(root, working_set_size);
|
||||||
|
|
||||||
|
// }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// void build_sequencial_ll(struct l * root, long working_set_size)
|
||||||
|
void build_sequencial_ll(struct l *root, long working_set_size)
|
||||||
|
{
|
||||||
|
|
||||||
|
unsigned long i;
|
||||||
|
|
||||||
|
struct l *current;
|
||||||
|
|
||||||
|
|
||||||
|
for(i=0;i<(working_set_size/sizeof(struct l));i++)
|
||||||
|
{
|
||||||
|
current=root+i;
|
||||||
|
if(i==(working_set_size/sizeof(struct l)-1))
|
||||||
|
current->n=root;
|
||||||
|
else
|
||||||
|
current->n=current+1;
|
||||||
|
if(i==0)
|
||||||
|
current->p=root+working_set_size/sizeof(struct l)-1;
|
||||||
|
else
|
||||||
|
current->p=current-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// void build_random_ll(struct l *root, long working_set_size)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// unsigned long i;
|
||||||
|
|
||||||
|
|
||||||
|
// struct l *a;
|
||||||
|
// struct l *b;
|
||||||
|
// struct l *oldan;
|
||||||
|
// struct l *oldbn;
|
||||||
|
// struct l *oldap;
|
||||||
|
// struct l *oldbp;
|
||||||
|
|
||||||
|
// unsigned long rnd;
|
||||||
|
// unsigned long tries;
|
||||||
|
|
||||||
|
// build_sequencial_ll(root, working_set_size);
|
||||||
|
|
||||||
|
// //construct the array of elements
|
||||||
|
// //link the list to the next element in the array
|
||||||
|
|
||||||
|
// for(i=1;i<(working_set_size/sizeof(struct l)-1);i++)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// a=(root+i);
|
||||||
|
// b=a;
|
||||||
|
// tries=5;
|
||||||
|
// while((b==a || b==root) && tries)
|
||||||
|
// {
|
||||||
|
// rnd=rand64() % (working_set_size/sizeof(struct l)-1);
|
||||||
|
// b=root+rnd;
|
||||||
|
// tries--;
|
||||||
|
// }
|
||||||
|
// if(!tries)
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
|
||||||
|
// oldan=a->n; //a->n is lost along the way
|
||||||
|
// oldbn=b->n; //b->n is lost along the way
|
||||||
|
// oldap=a->p; //a->p is lost along the way
|
||||||
|
// oldbp=b->p; //b->p is lost along the way
|
||||||
|
|
||||||
|
// a->p->n=b;
|
||||||
|
// b->p->n=a;
|
||||||
|
|
||||||
|
// if(b!=oldan)
|
||||||
|
// {
|
||||||
|
// b->n=oldan;
|
||||||
|
// oldan->p=b;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// b->n=a;
|
||||||
|
// a->p=b;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if(a!=oldbn)
|
||||||
|
// {
|
||||||
|
// a->n=oldbn;
|
||||||
|
// oldbn->p=a;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// a->n=b;
|
||||||
|
// b->p=a;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if(b!=oldap)
|
||||||
|
// b->p=oldap;
|
||||||
|
// else
|
||||||
|
// b->p=a;
|
||||||
|
|
||||||
|
// if(a!=oldbp)
|
||||||
|
// a->p=oldbp;
|
||||||
|
// else
|
||||||
|
// a->p=b;
|
||||||
|
|
||||||
|
|
||||||
|
// #ifdef DEBUG
|
||||||
|
// printf("DEBUG: Round i=%ld\n",i);
|
||||||
|
// printf("DEBUG: A=%ld B=%ld\n",a-root,b-root);
|
||||||
|
// print_ll(root, working_set_size);
|
||||||
|
// #endif
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct thread_start_data
|
||||||
|
{
|
||||||
|
struct l *root;
|
||||||
|
unsigned long working_set_size;
|
||||||
|
int thread_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
void * walk(void *param)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct thread_start_data *data=param;
|
||||||
|
unsigned long start,end;
|
||||||
|
|
||||||
|
|
||||||
|
struct l *root=data->root;
|
||||||
|
// struct l* current=root->n;
|
||||||
|
struct l *current = root->n;
|
||||||
|
|
||||||
|
// #ifdef __MACH__
|
||||||
|
// start=mach_absolute_time();
|
||||||
|
// #else
|
||||||
|
// struct timespec ts;
|
||||||
|
// clock_gettime(CLOCK_MONOTONIC_RAW,&ts);
|
||||||
|
// start=ts.tv_nsec;
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
//traverse the linked list
|
||||||
|
|
||||||
|
while(current!=root)
|
||||||
|
{
|
||||||
|
// #ifdef ADDTEST
|
||||||
|
// current->pad[0]+=current->n->pad[0];
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef INCTEST
|
||||||
|
// current->pad[0]++;
|
||||||
|
// #endif
|
||||||
|
current=current->n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// #ifdef __MACH__
|
||||||
|
// end=mach_absolute_time();
|
||||||
|
// #else
|
||||||
|
// clock_gettime(CLOCK_MONOTONIC_RAW,&ts);
|
||||||
|
// end=ts.tv_nsec;
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
|
||||||
|
// printf("%d,%ld,%ld,%ld\n",data->thread_index,data->working_set_size, end-start, data->working_set_size/sizeof(struct l));
|
||||||
|
|
||||||
|
// free(data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// clock_t tic = clock();
|
||||||
|
// INITREGULARALLOC();
|
||||||
|
//#ifdef DEBUG
|
||||||
|
// printf("DEBUG:sizeof(struct l)=%ld\n",sizeof(struct l));
|
||||||
|
// #endif
|
||||||
|
struct l *root;
|
||||||
|
unsigned long working_set_size;
|
||||||
|
int i;
|
||||||
|
// struct thread_start_data *tdata;
|
||||||
|
struct thread_start_data *tdata;
|
||||||
|
|
||||||
|
|
||||||
|
// pthread_t threads[NTHREADS];
|
||||||
|
|
||||||
|
root=malloc(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)
|
||||||
|
{
|
||||||
|
|
||||||
|
// #ifdef DEBUG
|
||||||
|
// printf("DEBUG:Working set size=%ld elements=%ld\n",working_set_size,working_set_size/sizeof(struct l));
|
||||||
|
// #endif
|
||||||
|
// clock_t toc = clock();
|
||||||
|
// printf("Elapsed build get here before ll: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);
|
||||||
|
// #ifdef RANDOM_LIST
|
||||||
|
// build_random_ll(root, working_set_size);
|
||||||
|
// #else
|
||||||
|
// clock_t tic1 = clock();
|
||||||
|
build_sequencial_ll(root, working_set_size);
|
||||||
|
// build_sequencial_ll(root, working_set_size);
|
||||||
|
// clock_t toc1 = clock();
|
||||||
|
// printf("Elapsed build ll: %f seconds\n", (double)(toc1 - tic1) / CLOCKS_PER_SEC);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #if NTHREADS>0
|
||||||
|
// for(i=0;i<NTHREADS;i++)
|
||||||
|
// {
|
||||||
|
// tdata= malloc(sizeof(struct thread_start_data));
|
||||||
|
// tdata->thread_index=i;
|
||||||
|
// tdata->root=root;
|
||||||
|
// tdata->working_set_size=working_set_size;
|
||||||
|
// pthread_create(&threads[i], NULL, walk, (void*) tdata);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for(i=0;i<NTHREADS;i++)
|
||||||
|
// pthread_join(threads[i],NULL);
|
||||||
|
// #else
|
||||||
|
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 < 64; i++) {
|
||||||
|
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 < 64; i++) {
|
||||||
|
// walk(tdata);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// clock_t toc2 = clock();
|
||||||
|
// printf("Elapsed build walk: %f seconds\n", (double)(toc2 - tic2) / CLOCKS_PER_SEC);
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("-----------------------------------------------");
|
||||||
|
|
||||||
|
|
||||||
|
free(root);
|
||||||
|
root = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
46
Tests/isa/Cprograms/benchmark/richards/build.sh
Normal file
46
Tests/isa/Cprograms/benchmark/richards/build.sh
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
scp ../../encoding.h home-1:/home/akilan/
|
||||||
|
scp ../../entry.S home-1:/home/akilan/
|
||||||
|
scp ../../link.ld home-1:/home/akilan/
|
||||||
|
scp ../../riscv_test_p.h home-1:/home/akilan/
|
||||||
|
scp ../../riscv_test.h home-1:/home/akilan/
|
||||||
|
scp ../../string.c home-1:/home/akilan/
|
||||||
|
scp ../../vm.c home-1:/home/akilan/
|
||||||
|
scp ../../test.S home-1:/home/akilan/
|
||||||
|
scp ../../test_macros.h home-1:/home/akilan/
|
||||||
|
scp ../../malloc.c home-1:/home/akilan/
|
||||||
|
|
||||||
|
# scp ../../test.c home-1:/home/akilan/
|
||||||
|
scp richards.c home-1:/home/akilan/
|
||||||
|
|
||||||
|
# GCC compile
|
||||||
|
# ssh home-1 'cd /home/akilan/ && export PATH=/opt/riscv/bin:$PATH && riscv64-unknown-elf-gcc -DENTROPY=0xf21e02b -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -mabi=lp64 -T link.ld vm.c string.c entry.S test.S -o testC'
|
||||||
|
|
||||||
|
# Clang compile (architecture Regular RISCV)
|
||||||
|
ssh home-1 'clang --target=riscv64-unknown-elf -DENTROPY=0xf21e02b -DDEFINE_MALLOC -DDEFINE_FREE --gcc-toolchain=/opt/riscv -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -fno-builtin-malloc -mabi=lp64 -T link.ld vm.c string.c malloc.c entry.S test.S richards.c -o testC'
|
||||||
|
|
||||||
|
# Clang using the cheri clang compiler
|
||||||
|
# ssh home-1 'cd cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-freebsd -DENTROPY=0xf21e02b --sysroot=cheribsd-riscv64-for-purecap-rootfs.cfg -mcmodel=medany -nostdlib -nostartfiles -ffreestanding -fno-builtin -march=rv64imafdcxcheri -mabi=lp64d -T link.ld vm.c string.c entry.S test.S -o testC'
|
||||||
|
|
||||||
|
scp home-1:/home/akilan/testC ../../../
|
||||||
|
|
||||||
|
# scp home-1:/home/akilan/cheri/output/sdk/bin/testC .
|
||||||
|
|
||||||
|
# riscv64-unknown-elf-gcc \
|
||||||
|
# -march=rv64imac \
|
||||||
|
# -mabi=lp64 \
|
||||||
|
# -nostartfiles \
|
||||||
|
# -fno-builtin \
|
||||||
|
# -T link.ld \
|
||||||
|
# entry.S vm.c string.c \
|
||||||
|
|
||||||
|
# clang \
|
||||||
|
# --target=riscv64-unknown-elf \
|
||||||
|
# -march=rv64imac \
|
||||||
|
# -mabi=lp64 \
|
||||||
|
# -nostdlib \
|
||||||
|
# -nostartfiles \
|
||||||
|
# -fuse-ld=lld \
|
||||||
|
# -T link.ld \
|
||||||
|
# entry.S vm.c string.c \
|
||||||
|
# -I. \
|
||||||
|
# -o output.elf%
|
||||||
455
Tests/isa/Cprograms/benchmark/richards/richards.c
Normal file
455
Tests/isa/Cprograms/benchmark/richards/richards.c
Normal file
@@ -0,0 +1,455 @@
|
|||||||
|
// 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* malloc(size_t);
|
||||||
|
void 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 *)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 *)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(void)
|
||||||
|
{
|
||||||
|
//INITREGULARALLOC();
|
||||||
|
int iterations = 2;
|
||||||
|
int warmup = 0;
|
||||||
|
int inner_iterations = 2;
|
||||||
|
|
||||||
|
// parse_argv(argc, argv, &iterations, &warmup, &inner_iterations);
|
||||||
|
|
||||||
|
// while(1);
|
||||||
|
|
||||||
|
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--;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,5 +15,5 @@ SECTIONS
|
|||||||
_end = .;
|
_end = .;
|
||||||
|
|
||||||
__malloc_start = .;
|
__malloc_start = .;
|
||||||
. = . + 512;
|
. = . + 0x10000;
|
||||||
}
|
}
|
||||||
@@ -4,41 +4,41 @@
|
|||||||
|
|
||||||
void* malloc(size_t size);
|
void* malloc(size_t size);
|
||||||
|
|
||||||
int main(void)
|
int main(void) {
|
||||||
{
|
// char *a = malloc(30);
|
||||||
char* a = malloc(50);
|
// char *b = malloc(16);
|
||||||
char* b = malloc(160);
|
|
||||||
|
|
||||||
// asm volatile("fence rw, rw"); // make sure store completes
|
|
||||||
|
|
||||||
// volatile uint64_t* marker = (uint64_t*)0x80001000;
|
|
||||||
|
|
||||||
// *marker = 0xCAFEBABECAFED00D; // UNIQUE SIGNATURE
|
|
||||||
|
|
||||||
|
|
||||||
// if (!a || !b) return;
|
// // if (!a || !b) return -1;
|
||||||
|
|
||||||
a[0] = 'A';
|
// a[0] = 'A';
|
||||||
|
// a[1] = 'C';
|
||||||
// // a[1] = 'C';
|
// b[0] = 'B';
|
||||||
// // b[0] = 'B';
|
|
||||||
|
|
||||||
// // This will fault (out-of-bounds)
|
// // This will fault (out-of-bounds)
|
||||||
// // a[20] = 'X';
|
// // a[20] = 'X';
|
||||||
|
|
||||||
if (a[0] != 'A') {
|
// if (a[1] != 'C') {
|
||||||
while (1);
|
// while (1);
|
||||||
}
|
|
||||||
// // char* a = malloc(100);
|
|
||||||
// // char* b = malloc(200);
|
|
||||||
|
|
||||||
// a[0] = 'A'; // triggers page fault if unmapped
|
|
||||||
// b[19] = 'Z';
|
|
||||||
|
|
||||||
// for (int i = 0; i < 1000; i++) {
|
|
||||||
// a[i * 64] = i; // each write new cache line
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// if (b[0] != 'B') {
|
||||||
// while (1);
|
// while (1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // free(b);
|
||||||
|
// // b = NULL;
|
||||||
|
|
||||||
|
// // if (b[0] == 'B') {
|
||||||
|
// // while (1);
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// char *c = malloc(16);
|
||||||
|
|
||||||
|
// // if (c[0] != 'B') {
|
||||||
|
// // while (1);
|
||||||
|
// // }
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -333,7 +333,7 @@ void vm_boot(uintptr_t test_addr)
|
|||||||
trapframe_t tf;
|
trapframe_t tf;
|
||||||
memset(&tf, 0, sizeof(tf));
|
memset(&tf, 0, sizeof(tf));
|
||||||
tf.epc = test_addr - DRAM_BASE;
|
tf.epc = test_addr - DRAM_BASE;
|
||||||
// call test function
|
// call C benchmark function
|
||||||
main();
|
main();
|
||||||
pop_tf(&tf);
|
pop_tf(&tf);
|
||||||
}
|
}
|
||||||
BIN
Tests/isa/testC
BIN
Tests/isa/testC
Binary file not shown.
92
analysis/graph.py
Normal file
92
analysis/graph.py
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
performance_data = {
|
||||||
|
"Mem": {
|
||||||
|
"regular": {"CPU_cycles": 33940, "L1_DTLB_access": 13202, "L1_DTLB_miss": 36, "L2_DTLB_miss": 10},
|
||||||
|
"modified": {"CPU_cycles": 2457, "L1_DTLB_access": 151, "L1_DTLB_miss": 0, "L2_DTLB_miss": 0},
|
||||||
|
},
|
||||||
|
"Test_C": {
|
||||||
|
"regular": {"CPU_cycles": 34040, "L1_DTLB_access": 13284, "L1_DTLB_miss": 36, "L2_DTLB_miss": 10},
|
||||||
|
"modified": {"CPU_cycles": 2789, "L1_DTLB_access": 396, "L1_DTLB_miss": 0, "L2_DTLB_miss": 0},
|
||||||
|
},
|
||||||
|
"Glibc": {
|
||||||
|
"regular": {"CPU_cycles": 36053, "L1_DTLB_access": 14027, "L1_DTLB_miss": 36, "L2_DTLB_miss": 10},
|
||||||
|
"modified": {"CPU_cycles": 4219, "L1_DTLB_access": 783, "L1_DTLB_miss": 0, "L2_DTLB_miss": 0},
|
||||||
|
},
|
||||||
|
"Richards": {
|
||||||
|
"regular": {"CPU_cycles": 37808, "L1_DTLB_access": 14363, "L1_DTLB_miss": 10, "L2_DTLB_miss": 6},
|
||||||
|
"modified": {"CPU_cycles": 4433, "L1_DTLB_access": 874, "L1_DTLB_miss": 0, "L2_DTLB_miss": 0},
|
||||||
|
},
|
||||||
|
"Matrix_mul": {
|
||||||
|
"regular": {"CPU_cycles": 42383, "L1_DTLB_access": 17020, "L1_DTLB_miss": 14, "L2_DTLB_miss": 10},
|
||||||
|
"modified": {"CPU_cycles": 12149, "L1_DTLB_access": 4411, "L1_DTLB_miss": 0, "L2_DTLB_miss": 0},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def compute_percent_diff(regular, modified):
|
||||||
|
out = {}
|
||||||
|
for k in regular:
|
||||||
|
if k in modified and regular[k] != 0:
|
||||||
|
out[k] = ((regular[k] - modified[k]) / regular[k]) * 100
|
||||||
|
elif k in modified and regular[k] == 0 and modified[k] == 0:
|
||||||
|
out[k] = 0.0
|
||||||
|
elif k in modified and regular[k] == 0 and modified[k] != 0:
|
||||||
|
out[k] = -100.0
|
||||||
|
return out
|
||||||
|
|
||||||
|
for t, d in performance_data.items():
|
||||||
|
d["percent_diff"] = compute_percent_diff(d["regular"], d["modified"])
|
||||||
|
|
||||||
|
tests = list(performance_data.keys())
|
||||||
|
metrics = ["CPU_cycles", "L1_DTLB_access", "L1_DTLB_miss", "L2_DTLB_miss"]
|
||||||
|
|
||||||
|
# 1. Summary plot: Percent Improvement for all metrics grouped by test
|
||||||
|
x = np.arange(len(tests))
|
||||||
|
width = 0.2
|
||||||
|
fig, ax = plt.subplots(figsize=(12, 7))
|
||||||
|
|
||||||
|
for i, metric in enumerate(metrics):
|
||||||
|
values = [performance_data[t]["percent_diff"].get(metric, 0) for t in tests]
|
||||||
|
offset = (i - len(metrics)/2 + 0.5) * width
|
||||||
|
ax.bar(x + offset, values, width, label=metric.replace('_', ' ').title())
|
||||||
|
|
||||||
|
ax.set_ylabel('Percent Improvement (%)')
|
||||||
|
ax.set_title('Percent Improvement (Regular -> Modified) by Test and Metric')
|
||||||
|
ax.set_xticks(x)
|
||||||
|
ax.set_xticklabels(tests)
|
||||||
|
ax.legend()
|
||||||
|
ax.set_ylim(0, 110)
|
||||||
|
ax.grid(axis='y', linestyle='--', alpha=0.7)
|
||||||
|
fig.tight_layout()
|
||||||
|
plt.savefig('percent_improvement_summary.png')
|
||||||
|
|
||||||
|
# 2. Individual metric plots: Regular vs Modified grouped by test
|
||||||
|
y_label_map = {
|
||||||
|
"CPU_cycles": "Cycles",
|
||||||
|
"L1_DTLB_access": "Access Count",
|
||||||
|
"L1_DTLB_miss": "Miss Count",
|
||||||
|
"L2_DTLB_miss": "Miss Count"
|
||||||
|
}
|
||||||
|
|
||||||
|
for metric in metrics:
|
||||||
|
fig, ax = plt.subplots(figsize=(10, 6))
|
||||||
|
reg_vals = [performance_data[t]["regular"][metric] for t in tests]
|
||||||
|
mod_vals = [performance_data[t]["modified"][metric] for t in tests]
|
||||||
|
|
||||||
|
x_local = np.arange(len(tests))
|
||||||
|
w = 0.35
|
||||||
|
|
||||||
|
ax.bar(x_local - w/2, reg_vals, w, label='Regular', color='steelblue')
|
||||||
|
ax.bar(x_local + w/2, mod_vals, w, label='Modified', color='salmon')
|
||||||
|
|
||||||
|
# Setting dynamic y-label
|
||||||
|
ax.set_ylabel(y_label_map.get(metric, metric.replace('_', ' ').title()))
|
||||||
|
ax.set_title(f'Comparison: {metric.replace("_", " ").title()}')
|
||||||
|
ax.set_xticks(x_local)
|
||||||
|
ax.set_xticklabels(tests)
|
||||||
|
ax.legend()
|
||||||
|
ax.grid(axis='y', linestyle='--', alpha=0.7)
|
||||||
|
plt.xticks(rotation=45)
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.savefig(f'grouped_comparison_{metric}.png')
|
||||||
BIN
analysis/grouped_comparison_CPU_cycles.png
Normal file
BIN
analysis/grouped_comparison_CPU_cycles.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
BIN
analysis/grouped_comparison_L1_DTLB_access.png
Normal file
BIN
analysis/grouped_comparison_L1_DTLB_access.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
BIN
analysis/grouped_comparison_L1_DTLB_miss.png
Normal file
BIN
analysis/grouped_comparison_L1_DTLB_miss.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
BIN
analysis/grouped_comparison_L2_DTLB_miss.png
Normal file
BIN
analysis/grouped_comparison_L2_DTLB_miss.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
BIN
analysis/percent_improvement_summary.png
Normal file
BIN
analysis/percent_improvement_summary.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
145
analysis/perf_data.py
Normal file
145
analysis/perf_data.py
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
def compute_percent_diff(regular, modified):
|
||||||
|
percent_diff = {}
|
||||||
|
for key in regular:
|
||||||
|
if key in modified and regular[key] != 0:
|
||||||
|
percent_diff[key] = ((regular[key] - modified[key]) / regular[key]) * 100
|
||||||
|
return percent_diff
|
||||||
|
|
||||||
|
def compute_percent_diff_mod_vs_pte(modified, after_pte):
|
||||||
|
percent_diff = {}
|
||||||
|
for key in ["CPU_cycles", "L1_DTLB_access"]:
|
||||||
|
if key in modified and key in after_pte and modified[key] != 0:
|
||||||
|
percent_diff[key] = ((modified[key] - after_pte[key]) / modified[key]) * 100
|
||||||
|
return percent_diff
|
||||||
|
|
||||||
|
|
||||||
|
performance_data = {
|
||||||
|
"Mem": {
|
||||||
|
"regular": {
|
||||||
|
"CPU_cycles": 33940,
|
||||||
|
"L1_DTLB_access": 13202,
|
||||||
|
"L1_DTLB_miss": 36,
|
||||||
|
"L2_DTLB_miss": 10,
|
||||||
|
},
|
||||||
|
"modified": {
|
||||||
|
"CPU_cycles": 2457,
|
||||||
|
"L1_DTLB_access": 151,
|
||||||
|
"L1_DTLB_miss": 0,
|
||||||
|
"L2_DTLB_miss": 0,
|
||||||
|
},
|
||||||
|
"after_PTE_setup": {
|
||||||
|
"CPU_cycles": 531,
|
||||||
|
"L1_DTLB_access": 25,
|
||||||
|
"L1_DTLB_miss": 0,
|
||||||
|
"L2_DTLB_miss": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"Test_C": {
|
||||||
|
"regular": {
|
||||||
|
"CPU_cycles": 34040,
|
||||||
|
"L1_DTLB_access": 13284,
|
||||||
|
"L1_DTLB_miss": 36,
|
||||||
|
"L2_DTLB_miss": 10,
|
||||||
|
},
|
||||||
|
"modified": {
|
||||||
|
"CPU_cycles": 2789,
|
||||||
|
"L1_DTLB_access": 396,
|
||||||
|
"L1_DTLB_miss": 0,
|
||||||
|
"L2_DTLB_miss": 0,
|
||||||
|
},
|
||||||
|
"after_PTE_setup": {
|
||||||
|
"CPU_cycles": 631,
|
||||||
|
"L1_DTLB_access": 107,
|
||||||
|
"L1_DTLB_miss": 0,
|
||||||
|
"L2_DTLB_miss": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"Glibc": {
|
||||||
|
"regular": {
|
||||||
|
"CPU_cycles": 36053,
|
||||||
|
"L1_DTLB_access": 14027,
|
||||||
|
"L1_DTLB_miss": 36,
|
||||||
|
"L2_DTLB_miss": 10,
|
||||||
|
},
|
||||||
|
"modified": {
|
||||||
|
"CPU_cycles": 4219,
|
||||||
|
"L1_DTLB_access": 783,
|
||||||
|
"L1_DTLB_miss": 0,
|
||||||
|
"L2_DTLB_miss": 0,
|
||||||
|
},
|
||||||
|
"after_PTE_setup": {
|
||||||
|
"CPU_cycles": 2644,
|
||||||
|
"L1_DTLB_access": 850,
|
||||||
|
"L1_DTLB_miss": 0,
|
||||||
|
"L2_DTLB_miss": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"Setup": {
|
||||||
|
"regular": {
|
||||||
|
"CPU_cycles": 33409,
|
||||||
|
"L1_DTLB_access": 13177,
|
||||||
|
"L1_DTLB_miss": 36,
|
||||||
|
"L2_DTLB_miss": 10,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"Richards": {
|
||||||
|
"regular": {
|
||||||
|
"CPU_cycles": 37808,
|
||||||
|
"L1_DTLB_access": 14363,
|
||||||
|
"L1_DTLB_miss": 10,
|
||||||
|
"L2_DTLB_miss": 6,
|
||||||
|
},
|
||||||
|
"modified": {
|
||||||
|
"CPU_cycles": 4433,
|
||||||
|
"L1_DTLB_access": 874,
|
||||||
|
"L1_DTLB_miss": 0,
|
||||||
|
"L2_DTLB_miss": 0,
|
||||||
|
},
|
||||||
|
"after_PTE_setup": {
|
||||||
|
"CPU_cycles": 4399,
|
||||||
|
"L1_DTLB_access": 1186,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"Matrix_mul": {
|
||||||
|
"regular": {
|
||||||
|
"CPU_cycles": 42383,
|
||||||
|
"L1_DTLB_access": 17020,
|
||||||
|
"L1_DTLB_miss": 14,
|
||||||
|
"L2_DTLB_miss": 10,
|
||||||
|
},
|
||||||
|
"modified": {
|
||||||
|
"CPU_cycles": 12149,
|
||||||
|
"L1_DTLB_access": 4411,
|
||||||
|
"L1_DTLB_miss": 0,
|
||||||
|
"L2_DTLB_miss": 0,
|
||||||
|
},
|
||||||
|
"after_PTE_setup": {
|
||||||
|
"CPU_cycles": 8974,
|
||||||
|
"L1_DTLB_access": 3843,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add percentage differences
|
||||||
|
for test, data in performance_data.items():
|
||||||
|
if "regular" in data and "modified" in data:
|
||||||
|
data["percent_diff"] = compute_percent_diff(
|
||||||
|
data["regular"], data["modified"]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Add modified vs after_PTE_setup percentage differences
|
||||||
|
for test, data in performance_data.items():
|
||||||
|
if "modified" in data and "after_PTE_setup" in data:
|
||||||
|
data["mod_vs_pte_percent_diff"] = compute_percent_diff_mod_vs_pte(
|
||||||
|
data["modified"], data["after_PTE_setup"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Example usage:
|
||||||
|
print(performance_data["Mem"]["percent_diff"])
|
||||||
|
print(performance_data["Mem"]["mod_vs_pte_percent_diff"])
|
||||||
BIN
builds/.DS_Store
vendored
Normal file
BIN
builds/.DS_Store
vendored
Normal file
Binary file not shown.
1
builds/RV64ACDFIMSUxCHERI_Toooba_bluesim/.gitignore
vendored
Normal file
1
builds/RV64ACDFIMSUxCHERI_Toooba_bluesim/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.txt
|
||||||
File diff suppressed because it is too large
Load Diff
Submodule libs/TagController updated: 720ee78f58...34588beed4
0
richards.txt
Normal file
0
richards.txt
Normal file
0
richards_reg_10.txt
Normal file
0
richards_reg_10.txt
Normal 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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 :: *;
|
||||||
|
|
||||||
@@ -241,12 +241,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;
|
||||||
@@ -262,12 +262,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);
|
||||||
@@ -281,7 +281,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);
|
||||||
@@ -305,14 +305,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;
|
||||||
@@ -376,17 +376,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);
|
||||||
@@ -404,17 +404,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);
|
||||||
@@ -431,17 +431,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
|
||||||
@@ -503,12 +503,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
|
||||||
@@ -564,11 +564,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
|
||||||
@@ -744,7 +744,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);
|
||||||
@@ -758,7 +758,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);
|
||||||
@@ -795,11 +795,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
|
||||||
|
|
||||||
//=======================================================
|
//=======================================================
|
||||||
@@ -822,10 +822,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
|
||||||
@@ -839,12 +839,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));
|
||||||
@@ -852,7 +852,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)
|
||||||
@@ -862,14 +862,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
|
||||||
|
|
||||||
@@ -911,14 +911,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?
|
||||||
@@ -1029,7 +1029,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);
|
||||||
@@ -1038,7 +1038,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
|
||||||
@@ -1320,7 +1320,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
|
||||||
@@ -1330,7 +1330,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
|
||||||
@@ -1373,7 +1373,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);
|
||||||
@@ -1382,7 +1382,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
|
||||||
@@ -1435,16 +1435,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
|
||||||
@@ -1482,7 +1482,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);
|
||||||
@@ -1491,7 +1491,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
|
||||||
@@ -1661,7 +1661,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;
|
||||||
@@ -1677,14 +1677,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
|
||||||
|
|||||||
@@ -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 ();
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -242,11 +242,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));
|
||||||
@@ -257,11 +258,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);
|
||||||
@@ -357,24 +358,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
|
||||||
missPeerLat.incr(zeroExtend(lat));
|
missPeerLat.incr(zeroExtend(lat));
|
||||||
|
$display("L1 TLB miss");
|
||||||
|
$display("L1TLBmissPeerLat = %0d", missPeerLat);
|
||||||
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
|
||||||
@@ -508,12 +513,13 @@ module mkDTlb#(
|
|||||||
$display("[DTLB] req (hit): idx %d; ", idx, fshow(r),
|
$display("[DTLB] req (hit): idx %d; ", idx, fshow(r),
|
||||||
"; ", fshow(trans_result));
|
"; ", fshow(trans_result));
|
||||||
end
|
end
|
||||||
`ifdef PERF_COUNT
|
// `ifdef PERF_COUNT
|
||||||
// perf: hit under miss
|
// perf: hit under miss
|
||||||
if(doStats && readVReg(pendWait) != replicate(None)) begin
|
if(doStats && readVReg(pendWait) != replicate(None)) begin
|
||||||
hitUnderMissCnt.incr(1);
|
hitUnderMissCnt.incr(1);
|
||||||
|
$display("L1TlbhitUnderMissCnt = %0d", hitUnderMissCnt);
|
||||||
end
|
end
|
||||||
`endif
|
// `endif
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
// page fault
|
// page fault
|
||||||
@@ -565,17 +571,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
|
||||||
@@ -632,11 +639,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);
|
||||||
@@ -644,27 +651,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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)),
|
||||||
|
|||||||
15
test.txt
15
test.txt
@@ -1,12 +1,5 @@
|
|||||||
Let me know if this message works well on behalf of all of us.
|
- [ ] Benchmarks to port over:
|
||||||
|
- [ ] Barnes (3)
|
||||||
Hi Jan,
|
- [ ] Matrix multiplication (2)
|
||||||
This is a very small gesture from Jose, Mathews, Yukang and Akilan. We have transferred 200 pounds equally contributed by all of us. As you are moving in and settling into your new place, we hope this can help you and Samantha cover certain expenses like buying furniture or for your very efficient interrail travel pass in the near future.
|
- [ ] Richards (1)
|
||||||
|
|
||||||
We will definetely miss the german embassy in Slatefort. Happy new year in advance from all of us!
|
|
||||||
|
|
||||||
Regards,
|
|
||||||
Jose, Mathews, Yukang and Akilan
|
|
||||||
(Your UK representation of transportation
|
|
||||||
reform)
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user