From f7acb6184544d96dda055ce42da3577255a01ff8 Mon Sep 17 00:00:00 2001 From: bje Date: Thu, 21 Jun 2001 13:37:08 +0000 Subject: [PATCH] 2001-06-21 Ben Elliston * cache.h (cache_component::hit_latency): New member. (cache_component::miss_latency): Likewise. * cache.cxx (cache_component ctor): Add attributes for these. (cache_component::write_any): Add miss latency for misaligned accesses. Set latency correctly for return. (cache_component::read_any): Add miss latency for misaligned accesses. Set latency correctly for return. (cache_component::read_line): Return the true result of reads. (cache_component::write_line): Likewise for writes. * hw-cache.txt: Document latency extensions. --- sid/component/cache/ChangeLog | 13 ++++++++ sid/component/cache/cache.cxx | 64 ++++++++++++++++++++++++++++------------ sid/component/cache/cache.h | 4 +++ sid/component/cache/hw-cache.txt | 9 ++++++ 4 files changed, 71 insertions(+), 19 deletions(-) diff --git a/sid/component/cache/ChangeLog b/sid/component/cache/ChangeLog index 20681a46f0..f0c323c7e2 100644 --- a/sid/component/cache/ChangeLog +++ b/sid/component/cache/ChangeLog @@ -1,3 +1,16 @@ +2001-06-21 Ben Elliston + + * cache.h (cache_component::hit_latency): New member. + (cache_component::miss_latency): Likewise. + * cache.cxx (cache_component ctor): Add attributes for these. + (cache_component::write_any): Add miss latency for misaligned + accesses. Set latency correctly for return. + (cache_component::read_any): Add miss latency for misaligned + accesses. Set latency correctly for return. + (cache_component::read_line): Return the true result of reads. + (cache_component::write_line): Likewise for writes. + * hw-cache.txt: Document latency extensions. + 2001-06-19 Ben Elliston * cache.cxx (CacheCreate): Re-work using sidutil::tokenize. diff --git a/sid/component/cache/cache.cxx b/sid/component/cache/cache.cxx index 2f4713c81d..d24fde6f19 100644 --- a/sid/component/cache/cache.cxx +++ b/sid/component/cache/cache.cxx @@ -121,6 +121,9 @@ cache_component::cache_component (unsigned assocy, &cache_component::set_nothing, "register"); + add_attribute ("hit-latency", &hit_latency, "setting"); + add_attribute ("miss-latency", &miss_latency, "setting"); + // FIXME: state save/restore } @@ -135,7 +138,7 @@ bus::status cache_component::write_any (host_int_4 addr, DataType data) { bool hit; - bus::status st; + bus::status st, read_status; if (UNLIKELY (downstream == 0)) return bus::unmapped; @@ -160,7 +163,10 @@ cache_component::write_any (host_int_4 addr, DataType data) } acache.expunge (line); } - return downstream->read (addr, data); + + st = downstream->read (addr, data); + st.latency += miss_latency; + return st; } cache_line& line = acache.find (acache.addr_to_tag (addr), hit); @@ -183,8 +189,8 @@ cache_component::write_any (host_int_4 addr, DataType data) { cache_line expelled_line (line_size); cache_line new_line (line_size, acache.addr_to_tag (addr)); - if ((st = read_line (new_line)) != bus::ok) - return st; + if ((read_status = read_line (new_line)) != bus::ok) + return read_status; new_line.insert (line_offset (new_line, addr), data); acache.replace (expelled_line, new_line); @@ -213,13 +219,21 @@ cache_component::write_any (host_int_4 addr, DataType data) return st; } } - return bus::ok; + + st = bus::ok; + if (hit) + st.latency = hit_latency; + else + st.latency = read_status.latency + miss_latency; + return st; } template bus::status cache_component::read_any (host_int_4 addr, DataType& data) { + bus::status st, read_status; + if (UNLIKELY (downstream == 0)) return bus::unmapped; @@ -231,12 +245,13 @@ cache_component::read_any (host_int_4 addr, DataType& data) { if (LIKELY (collect_p)) stats.misaligned_reads++; - return downstream->read (addr, data); + + st = downstream->read (addr, data); + st.latency += miss_latency; + return st; } bool hit; - bus::status st; - cache_line& line = acache.find (acache.addr_to_tag (addr), hit); if (LIKELY (hit)) { @@ -251,11 +266,10 @@ cache_component::read_any (host_int_4 addr, DataType& data) { cache_line expelled_line (line_size); cache_line new_line (line_size, acache.addr_to_tag (addr)); - - if ((st = read_line (new_line)) != bus::ok) - return st; - new_line.extract (line_offset (new_line, addr), data); + if ((read_status = read_line (new_line)) != bus::ok) + return read_status; + new_line.extract (line_offset (new_line, addr), data); acache.replace (expelled_line, new_line); if (collect_p) @@ -265,23 +279,34 @@ cache_component::read_any (host_int_4 addr, DataType& data) { // flush a dirty line being replaced if ((st = write_line (expelled_line)) != bus::ok) - return st; + return st; } } else - return downstream->read (addr, data); + { + st = downstream->read (addr, data); + st.latency += miss_latency; + return st; + } } - return bus::ok; + + st = bus::ok; + if (hit) + st.latency += hit_latency; + else + st.latency = read_status.latency + miss_latency; + return st; } bus::status cache_component::read_line (cache_line& line) { + bus::status st; host_int_4 base = acache.tag_to_addr (line.tag ()); for (host_int_4 offset = 0; offset < line_size; offset += 4) { sid::big_int_4 data; - bus::status st = downstream->read (base + offset, data); + st = downstream->read (base + offset, data); if (st != bus::ok) return st; line.insert (offset, data); @@ -289,25 +314,26 @@ cache_component::read_line (cache_line& line) line.unlock (); line.clean (); line.validate (); - return bus::ok; + return st; } bus::status cache_component::write_line (cache_line& line) { + bus::status st; host_int_4 base = acache.tag_to_addr (line.tag ()); for (host_int_4 offset = 0; offset < line_size; offset += 4) { sid::big_int_4 data; line.extract (offset, data); - bus::status st = downstream->write (base + offset, data); + st = downstream->write (base + offset, data); if (st != bus::ok) return st; } line.clean (); if (LIKELY (collect_p)) stats.flushes++; - return bus::ok; + return st; } void diff --git a/sid/component/cache/cache.h b/sid/component/cache/cache.h index 525306e09f..feeb29802b 100644 --- a/sid/component/cache/cache.h +++ b/sid/component/cache/cache.h @@ -14,6 +14,7 @@ using std::vector; using sid::bus; using sid::component; +using sid::host_int_2; using sid::host_int_4; using sidutil::fixed_attribute_map_component; @@ -181,6 +182,9 @@ private: unsigned line_size; unsigned cache_size; unsigned assoc; + + host_int_2 hit_latency; + host_int_2 miss_latency; }; #endif // CACHE_H diff --git a/sid/component/cache/hw-cache.txt b/sid/component/cache/hw-cache.txt index bd7b2b6117..994e1ebe14 100644 --- a/sid/component/cache/hw-cache.txt +++ b/sid/component/cache/hw-cache.txt @@ -123,6 +123,12 @@ address that falls on the line. Subsequently, a line can be unlocked by driving the "unlock" pin. + * Memory latency + The component models the effects of memory latency. The + "hit-latency" and "miss-latency" attribute values specify the + cumulative latencies for hit and missed cache operations. Any + misaligned accesses are penalised as if they are a miss. + * Statistics gathering The component gathers statistics for a number of significant events and records them in read-only attributes. The collection @@ -137,6 +143,7 @@ - SID conventions * This is a functional component. + * The component models memory latency. * It presents attributes in the "setting" and "register" categories. * Environment @@ -198,6 +205,8 @@ - write-hit-rate | register | %age string | 0% | statistics gathering - collect-statistics? | setting | boolean | true | statistics gathering - report-heading | setting | string | cache profile report | stats g. + - hit-latency | setting | numeric | 0 | memory latency + - miss-latency | setting | numeric | 0 | memory latency - dump! | setting | empty string | empty | internal diagnostics * References -- 2.11.0