diff --git a/src/dram/impl/HBM3.cpp b/src/dram/impl/HBM3.cpp
index fc921ea..ba83de0 100644
--- a/src/dram/impl/HBM3.cpp
+++ b/src/dram/impl/HBM3.cpp
@@ -2,0 +3 @@
+// Considering QDR DQ pins, we double dq pins and halve burst length. So, rate 2 actually means 4 Gbps DQs for HBM3.
@@ -11,4 +12,16 @@ class HBM3 : public IDRAM, public Implementation {
-      //   name     density   DQ    Ch Pch  Bg Ba   Ro     Co
-      {"HBM3_2Gb",   {2<<10,  128,  {1, 2,  4,  4, 1<<13, 1<<6}}},
-      {"HBM3_4Gb",   {4<<10,  128,  {1, 2,  4,  4, 1<<14, 1<<6}}},
-      {"HBM3_8Gb",   {6<<10,  128,  {1, 2,  4,  4, 1<<15, 1<<6}}},
+      // DQ for Pseudo Channel
+      // 1/2/3/4R means 1/2/3/4 ranks for 4/8/12/16-Hi stack
+      // We refer to JEDEC Standard (JESD238A).
+      //   name          density    DQ    Ch Pch  Ra  Bg  Ba   Ro     Co
+      {"HBM3_2Gb_1R",    {2<<10,    32,  {1,  2,  1,  4,  4, 1<<13,  1<<5}}},
+      {"HBM3_4Gb_1R",    {4<<10,    32,  {1,  2,  1,  4,  4, 1<<14,  1<<5}}},
+      {"HBM3_8Gb_1R",    {8<<10,    32,  {1,  2,  1,  4,  4, 1<<15,  1<<5}}},
+      {"HBM3_4Gb_2R",    {4<<10,    32,  {1,  2,  2,  4,  4, 1<<13,  1<<5}}},
+      {"HBM3_8Gb_2R",    {8<<10,    32,  {1,  2,  2,  4,  4, 1<<14,  1<<5}}},
+      {"HBM3_16Gb_2R",   {16<<10,   32,  {1,  2,  2,  4,  4, 1<<15,  1<<5}}},
+      {"HBM3_6Gb_3R",    {6<<10,    32,  {1,  2,  3,  4,  4, 1<<13,  1<<5}}},
+      {"HBM3_12Gb_3R",   {12<<10,   32,  {1,  2,  3,  4,  4, 1<<14,  1<<5}}},
+      {"HBM3_24Gb_3R",   {24<<10,   32,  {1,  2,  3,  4,  4, 1<<15,  1<<5}}},
+      {"HBM3_8Gb_4R",    {8<<10,    32,  {1,  2,  4,  4,  4, 1<<13,  1<<5}}},
+      {"HBM3_16Gb_4R",   {16<<10,   32,  {1,  2,  4,  4,  4, 1<<14,  1<<5}}},
+      {"HBM3_32Gb_4R",   {32<<10,   32,  {1,  2,  4,  4,  4, 1<<15,  1<<5}}},
@@ -19 +32,5 @@ class HBM3 : public IDRAM, public Implementation {
-      {"HBM3_2Gbps",  {2000,   4,   7,    7,      7,     7,   17,  19,   8,    2,     3,    2,    1,      2,     2,     3,     3,     4,    3,    15,   -1,   160,   3900,     -1,      8,   1000}},
+      {"HBM3_4.8Gbps",  {4800,   2,  17,   17,     17,    17,   41,  58,  20,    5,     8,    5,    2,      4,     2,     4,     8,    10,    3,    36,   -1,   240,   4680,     -1,     10,   1200}},
+      {"HBM3_5.2Gbps",  {5200,   2,  19,   19,     19,    19,   45,  63,  21,    6,     8,    6,    2,      4,     2,     4,     8,    11,    3,    39,   -1,   260,   5070,     -1,     11,   1300}},
+      {"HBM3_5.6Gbps",  {5600,   2,  20,   20,     20,    20,   48,  68,  23,    6,     9,    6,    2,      4,     2,     4,     9,    12,    3,    42,   -1,   280,   5460,     -1,     12,   1400}},
+      {"HBM3_6.0Gbps",  {6000,   2,  21,   21,     21,    21,   51,  72,  24,    6,     9,    6,    2,      4,     2,     4,     9,    12,    3,    45,   -1,   300,   5850,     -1,     12,   1500}},
+      {"HBM3_6.4Gbps",  {6400,   2,  23,   23,     23,    23,   55,  77,  26,    7,    10,    7,    2,      4,     2,     4,    10,    13,    3,    48,   -1,   320,   6240,     -1,     13,   1600}},
@@ -20,0 +38 @@ class HBM3 : public IDRAM, public Implementation {
+      // We could not find released HBM3 timing parameters. So, we mostly refer to the absolute value (ns) of the HBM2 timing parameters in DRAMSim3 (https://github.com/umd-memsys/DRAMsim3/blob/master/configs/HBM2_8Gb_x128.ini, commit: 29817593b3389f1337235d63cac515024ab8fd6e)
@@ -27 +45 @@ class HBM3 : public IDRAM, public Implementation {
-    const int m_internal_prefetch_size = 2;
+    const int m_internal_prefetch_size = 8;
@@ -30 +48 @@ class HBM3 : public IDRAM, public Implementation {
-      "channel", "pseudochannel", "bankgroup", "bank", "row", "column",    
+      "channel", "pseudochannel", "rank", "bankgroup", "bank", "row", "column",    
@@ -110,0 +129 @@ class HBM3 : public IDRAM, public Implementation {
+        {"rank",         "N/A"}, // SID
@@ -172 +191 @@ class HBM3 : public IDRAM, public Implementation {
-      m_channel_width = param_group("org").param<int>("channel_width").default_val(64);
+      m_channel_width = param_group("org").param<int>("channel_width").default_val(32);
@@ -203,0 +223 @@ class HBM3 : public IDRAM, public Implementation {
+                        size_t(m_organization.count[m_levels["rank"]]) *
@@ -208 +228,2 @@ class HBM3 : public IDRAM, public Implementation {
-                        size_t(m_organization.dq);
+                        size_t(m_organization.dq) *
+                        size_t(m_internal_prefetch_size);
@@ -242 +263 @@ class HBM3 : public IDRAM, public Implementation {
-      int tCK_ps = 1E6 / (m_timing_vals("rate") / 2);
+      int tCK_ps = 1E6 / (m_timing_vals("rate") / 4); // QDR DQ pins
@@ -247,3 +268,3 @@ class HBM3 : public IDRAM, public Implementation {
-      constexpr int tRFC_TABLE[1][4] = {
-      //  2Gb   4Gb   8Gb  16Gb
-        { 160,  260,  350,  450},
+      constexpr int tRFC_TABLE[1][8] = {
+      //  2Gb   4Gb   6Gb   8Gb   12Gb  16Gb  24Gb  32Gb
+        { 160,  260,  310,  350,  410,  450,  610,  650},
@@ -253,3 +274,3 @@ class HBM3 : public IDRAM, public Implementation {
-      constexpr int tREFISB_TABLE[1][4] = {
-      //  2Gb    4Gb    8Gb    16Gb
-        { 4875,  4875,  2438,  2438},
+      constexpr int tREFISB_TABLE[1][8] = {
+      //  4-Hi   8-Hi   12-Hi  16-Hi
+        { 244,   122,    82,    61},
@@ -262,2 +283,6 @@ class HBM3 : public IDRAM, public Implementation {
-          case 8192:  return 2;
-          case 16384: return 3;
+          case 6144:  return 2;
+          case 8192:  return 3;
+          case 12288: return 4;
+          case 16384: return 5;
+          case 24576: return 6;
+          case 32768: return 7;
@@ -269 +294 @@ class HBM3 : public IDRAM, public Implementation {
-      m_timing_vals("nREFISB")  = JEDEC_rounding(tRFC_TABLE[0][density_id], tCK_ps);
+      m_timing_vals("nREFISB")  = JEDEC_rounding(tREFISB_TABLE[0][m_organization.count[m_levels["rank"]]], tCK_ps);
@@ -302,13 +327 @@ class HBM3 : public IDRAM, public Implementation {
-          /*** Pseudo Channel (Table 3 — Array Access Timings Counted Individually Per Pseudo Channel, JESD-235C) ***/ 
-          // RAS <-> RAS
-          {.level = "pseudochannel", .preceding = {"ACT"}, .following = {"ACT"}, .latency = V("nRRDS")},
-          /// 4-activation window restriction
-          {.level = "pseudochannel", .preceding = {"ACT"}, .following = {"ACT"}, .latency = V("nFAW"), .window = 4},
-
-          /// ACT actually happens on the 2-nd cycle of ACT, so +1 cycle to nRRD
-          {.level = "pseudochannel", .preceding = {"ACT"}, .following = {"REFsb", "RFMsb"}, .latency = V("nRRDS") + 1},
-          /// nRREFD is the latency between REFsb <-> REFsb to *different* banks
-          {.level = "pseudochannel", .preceding = {"REFsb", "RFMsb"}, .following = {"REFsb", "RFMsb"}, .latency = V("nRREFD")},
-          /// nRREFD is the latency between REFsb <-> ACT to *different* banks. -1 as ACT happens on its 2nd cycle
-          {.level = "pseudochannel", .preceding = {"REFsb", "RFMsb"}, .following = {"ACT"}, .latency = V("nRREFD") - 1},
-
+          /*** Pseudo Channel ***/ 
@@ -319,10 +332 @@ class HBM3 : public IDRAM, public Implementation {
-
-          // CAS <-> CAS
-          /// nCCDS is the minimal latency for column commands 
-          {.level = "pseudochannel", .preceding = {"RD", "RDA"}, .following = {"RD", "RDA"}, .latency = V("nCCDS")},
-          {.level = "pseudochannel", .preceding = {"WR", "WRA"}, .following = {"WR", "WRA"}, .latency = V("nCCDS")},
-          /// RD <-> WR, Minimum Read to Write, Assuming tWPRE = 1 tCK                          
-          {.level = "pseudochannel", .preceding = {"RD", "RDA"}, .following = {"WR", "WRA"}, .latency = V("nCL") + V("nBL") + 2 - V("nCWL")},
-          /// WR <-> RD, Minimum Read after Write
-          {.level = "pseudochannel", .preceding = {"WR", "WRA"}, .following = {"RD", "RDA"}, .latency = V("nCWL") + V("nBL") + V("nWTRS")},
-          /// CAS <-> PREab
+          /// CAS <-> PREA
@@ -332,2 +335,0 @@ class HBM3 : public IDRAM, public Implementation {
-          {.level = "pseudochannel", .preceding = {"ACT"}, .following = {"ACT"}, .latency = V("nRRDS")},          
-          {.level = "pseudochannel", .preceding = {"ACT"}, .following = {"ACT"}, .latency = V("nFAW"), .window = 4},          
@@ -342,0 +345,28 @@ class HBM3 : public IDRAM, public Implementation {
+
+          /*** Rank (or different BankGroup) (Table 3 — Array Access Timings Counted Individually Per Pseudo Channel, JESD-235C) ***/  
+          // RAS <-> RAS
+          {.level = "rank", .preceding = {"ACT"}, .following = {"ACT"}, .latency = V("nRRDS")},
+          /// 4-activation window restriction
+          {.level = "rank", .preceding = {"ACT"}, .following = {"ACT"}, .latency = V("nFAW"), .window = 4},
+
+          /// ACT actually happens on the 2-nd cycle of ACT, so +1 cycle to nRRD
+          {.level = "rank", .preceding = {"ACT"}, .following = {"REFsb", "RFMsb"}, .latency = V("nRRDS") + 1},
+          /// nRREFD is the latency between REFsb <-> REFsb to *different* banks
+          {.level = "rank", .preceding = {"REFsb", "RFMsb"}, .following = {"REFsb", "RFMsb"}, .latency = V("nRREFD")},
+          /// nRREFD is the latency between REFsb <-> ACT to *different* banks. -1 as ACT happens on its 2nd cycle
+          {.level = "rank", .preceding = {"REFsb", "RFMsb"}, .following = {"ACT"}, .latency = V("nRREFD") - 1},
+
+          // CAS <-> CAS
+          /// nCCDS is the minimal latency for column commands 
+          {.level = "rank", .preceding = {"RD", "RDA"}, .following = {"RD", "RDA"}, .latency = V("nCCDS")},
+          {.level = "rank", .preceding = {"WR", "WRA"}, .following = {"WR", "WRA"}, .latency = V("nCCDS")},
+          /// RD <-> WR, Minimum Read to Write, Assuming tWPRE = 1 tCK                          
+          {.level = "rank", .preceding = {"RD", "RDA"}, .following = {"WR", "WRA"}, .latency = V("nCL") + V("nBL") + 2 - V("nCWL")},
+          /// WR <-> RD, Minimum Read after Write
+          {.level = "rank", .preceding = {"WR", "WRA"}, .following = {"RD", "RDA"}, .latency = V("nCWL") + V("nBL") + V("nWTRS")},
+          /// RAS <-> RAS
+          {.level = "rank", .preceding = {"ACT"}, .following = {"ACT"}, .latency = V("nRRDS")},          
+          {.level = "rank", .preceding = {"ACT"}, .following = {"ACT"}, .latency = V("nFAW"), .window = 4},          
+          {.level = "rank", .preceding = {"ACT"}, .following = {"PREA"}, .latency = V("nRAS")},          
+          {.level = "rank", .preceding = {"PREA"}, .following = {"ACT"}, .latency = V("nRP")},          
+
@@ -355 +384,0 @@ class HBM3 : public IDRAM, public Implementation {
-
@@ -375,2 +404,2 @@ class HBM3 : public IDRAM, public Implementation {
-      // Channel Actions
-      m_actions[m_levels["channel"]][m_commands["PREA"]] = Lambdas::Action::Channel::PREab<HBM3>;
+      // Pseudo Channel Actions
+      m_actions[m_levels["channel"]][m_commands["PREA"]] = Lambdas::Action::Channel::PREA<HBM3>;
@@ -378 +407 @@ class HBM3 : public IDRAM, public Implementation {
-      // Bank actions
+      // Bank Actions
@@ -388 +417 @@ class HBM3 : public IDRAM, public Implementation {
-      // Channel Actions
+      // Pseudo Channel Preqs
@@ -391 +420 @@ class HBM3 : public IDRAM, public Implementation {
-      // Bank actions
+      // Bank Preqs
