/* Author : Rick van der Zwet * S-number : 0433373 * Version : $Id: memory.h 363 2007-12-03 06:07:31Z rick $ * Copyright : FreeBSD Licence * Description : page-mode DRAM with a page-size of PAGESIZE words, a * random access time of RAS clock cycles and a 'next * access time' of NAT clock cycles. */ #include #include #include #include "common.h" void memory_dram(const int PAGESIZE, const int NAT, const int RAS) { struct bus2_t line; struct result_t output = {0, 0, 0, 0}; /* Keep track of which page memory is, cause switching means a lot of * extra work/cycles in terms of empty memory, moving to new bank */ int current_page = 0; /* Page location needed by new request */ int page_needed = 0; /* Part of page needed by new request */ int part_needed = 0; /* Every page has got 64 entries which all can be busy, * by convention 0 means not busy else busy */ int * partbusy = (int *)malloc(sizeof(int) * PAGESIZE); int i; /* Temp counter */ /* Init all parts to be available in the beginning */ memset(partbusy, FALSE, sizeof(int) * PAGESIZE); while (fscanfbus2(&line) != EOF) { /* Process the counts */ setstats(&line, &output); /* New request means new cycle as well */ output.cycles++; /* Find proper page, do not take advantage of C div operator on * int which is rounding directly, but use more safe/portable * approch */ part_needed = line.address % PAGESIZE; page_needed = (line.address - part_needed) / PAGESIZE; /* Determine wether we did hit the right page or not */ if (page_needed == current_page) { /* Check whether part is busy, which will result in waiting * till part access is granted */ if (partbusy[part_needed] != FALSE) { /* Worst case senario on refresh */ output.cycles += RAS; memset(partbusy, FALSE, sizeof(int) * PAGESIZE); } } else { /* Wait till all pending calls in current page are completed * 'Abuse' t to be identifier wether some bank was lowered */ /* Worst case senario on refresh */ output.cycles += RAS; memset(partbusy, FALSE, sizeof(int) * PAGESIZE); /* Switch to new page */ current_page = page_needed; output.cycles += NAT; output.conflicts++; } /* Set new memory access */ partbusy[part_needed] = RAS + TRANSFER; /* Process all parts to lower cycle count by one */ for (i = 0; i < PAGESIZE; i++) { if (partbusy[i] != FALSE) partbusy[i]--; } } /* Make sure remaining data leaves memory safely */ /* Worst case senario on refresh */ output.cycles += RAS; /* Delete allocated memory */ free(partbusy); printfresult(stdout, &output); }