diff --git a/memorysim/integration/src/main/scala/memorysim/integration/chipyard/SimMemorySimExecutor.scala b/memorysim/integration/src/main/scala/memorysim/integration/chipyard/SimMemorySimExecutor.scala index c3a568d..d782ad5 100644 --- a/memorysim/integration/src/main/scala/memorysim/integration/chipyard/SimMemorySimExecutor.scala +++ b/memorysim/integration/src/main/scala/memorysim/integration/chipyard/SimMemorySimExecutor.scala @@ -37,7 +37,7 @@ class SimMemorySimExecutor( memConfiguration = MemoryConfigurationParameters( addressWidth = addrBits, dataWidth = dataBits, - numberOfChannels = 1, + numberOfChannels = 4, numberOfRanks = 2, numberOfBanks = 8, memoryQueueSize = 8 diff --git a/memorysim/memctrl/src/main/resources/vsrc/BankPhysicalMemoryRequestPerformanceStatistics.sv b/memorysim/memctrl/src/main/resources/vsrc/BankPhysicalMemoryRequestPerformanceStatistics.sv index 474cd8a..19ba0c1 100644 --- a/memorysim/memctrl/src/main/resources/vsrc/BankPhysicalMemoryRequestPerformanceStatistics.sv +++ b/memorysim/memctrl/src/main/resources/vsrc/BankPhysicalMemoryRequestPerformanceStatistics.sv @@ -7,26 +7,24 @@ module BankPhysicalMemoryRequestPerformanceStatistics #( parameter int GLOBAL_CYCLE_BITS, parameter int REQUEST_ID_BITS )( - input wire clk, - input wire reset, - input wire req_fire, - input wire [ADDRESS_WIDTH-1:0] addr, - input wire [DATA_WIDTH-1:0] data, - input wire cs, - input wire ras, - input wire cas, - input wire we, - input wire [GLOBAL_CYCLE_BITS-1:0] globalCycle, - input wire [REQUEST_ID_BITS-1:0] request_id, - input wire [REQUEST_ID_BITS-1:0] internal_req_id, - input wire [REQUEST_ID_BITS-1:0] channel_id, - input wire [REQUEST_ID_BITS-1:0] rank_id, - input wire [REQUEST_ID_BITS-1:0] bank_id, - input wire [REQUEST_ID_BITS-1:0] scheduler_id + input wire clk, + input wire reset, + input wire req_fire, + input wire [ADDRESS_WIDTH-1:0] addr, + input wire [DATA_WIDTH-1:0] data, + input wire [DATA_WIDTH-1:0] op, // DRAMOp value (width defined upstream) + input wire [GLOBAL_CYCLE_BITS-1:0] globalCycle, + input wire [REQUEST_ID_BITS-1:0] request_id, + input wire [REQUEST_ID_BITS-1:0] internal_req_id, + input wire [REQUEST_ID_BITS-1:0] channel_id, + input wire [REQUEST_ID_BITS-1:0] rank_id, + input wire [REQUEST_ID_BITS-1:0] bank_id, + input wire [REQUEST_ID_BITS-1:0] scheduler_id ); integer file; reg [1023:0] filename; - + reg [8*24-1:0] opString; // longest string = "SELF REFRESH ENTER" + initial begin $sformat(filename, "bank_req_queue_stats_channel%0d_rank%0d_bank%0d.csv", CHANNEL, RANK, BANK); file = $fopen(filename, "w"); @@ -34,43 +32,21 @@ module BankPhysicalMemoryRequestPerformanceStatistics #( end always @(posedge clk) begin - if (reset) begin - end else if (req_fire) begin - if(cs == 0 && ras == 0 && cas == 0 && we == 1) begin - $fwrite(file, "%d,%d,%d,%d,%d,%d,%d,%s,%d\n", - request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, "REFRESH", globalCycle); - end - else if(cs == 0 && ras == 0 && cas == 1 && we == 0) begin - $fwrite(file, "%d,%d,%d,%d,%d,%d,%d,%s,%d\n", - request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, "PRECHARGE", globalCycle); - end - else if(cs == 0 && ras == 0 && cas == 1 && we == 1) begin - $fwrite(file, "%d,%d,%d,%d,%d,%d,%d,%s,%d\n", - request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, "ACTIVATE", globalCycle); - end - else if(cs == 0 && ras == 1 && cas == 0 && we == 1) begin - $fwrite(file, "%d,%d,%d,%d,%d,%d,%d,%s,%d\n", - request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, "READ", globalCycle); - end - else if(cs == 0 && ras == 1 && cas == 0 && we == 0) begin - $fwrite(file, "%d,%d,%d,%d,%d,%d,%d,%s,%d\n", - request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, "WRITE", globalCycle); - end - else if(cs == 0 && ras == 0 && cas == 0 && we == 0) begin - $fwrite(file, "%d,%d,%d,%d,%d,%d,%d,%s,%d\n", - request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, "SELF REFRESH ENTER", globalCycle); - end - else if(cs == 0 && ras == 1 && cas == 1 && we == 1) begin - $fwrite(file, "%d,%d,%d,%d,%d,%d,%d,%s,%d\n", - request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, "SELF REFRESH EXIT", globalCycle); - end + if (!reset && req_fire) begin + case (op) + 0: opString = "REFRESH"; + 1: opString = "PRECHARGE"; + 2: opString = "ACTIVATE"; + 3: opString = "READ"; + 4: opString = "WRITE"; + 5: opString = "SELF REFRESH ENTER"; + 6: opString = "SELF REFRESH EXIT"; + default: opString = "UNKNOWN"; + endcase + + $fwrite(file, "%0d,%0d,%0d,%0d,%0d,%0d,%0h,%s,%0d\n", + request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, + addr, opString, globalCycle); end end -endmodule \ No newline at end of file +endmodule diff --git a/memorysim/memctrl/src/main/resources/vsrc/BankSchedulerPhysicalMemoryRequestPerformanceStatistics.sv b/memorysim/memctrl/src/main/resources/vsrc/BankSchedulerPhysicalMemoryRequestPerformanceStatistics.sv index 9c2683c..1411e18 100644 --- a/memorysim/memctrl/src/main/resources/vsrc/BankSchedulerPhysicalMemoryRequestPerformanceStatistics.sv +++ b/memorysim/memctrl/src/main/resources/vsrc/BankSchedulerPhysicalMemoryRequestPerformanceStatistics.sv @@ -12,10 +12,7 @@ module BankSchedulerPhysicalMemoryRequestPerformanceStatistics #( input wire req_fire, input wire [ADDRESS_WIDTH-1:0] addr, input wire [DATA_WIDTH-1:0] data, - input wire cs, - input wire ras, - input wire cas, - input wire we, + input wire [DATA_WIDTH-1:0] op, // DRAMOp enum encoding input wire [GLOBAL_CYCLE_BITS-1:0] globalCycle, input wire [REQUEST_ID_BITS-1:0] request_id, input wire [REQUEST_ID_BITS-1:0] internal_req_id, @@ -27,55 +24,38 @@ module BankSchedulerPhysicalMemoryRequestPerformanceStatistics #( integer file; reg [1023:0] filename; - // Request type encoding (small integer IDs) - // +-----------------------+---------+ - // | String | ID | - // +-----------------------+---------+ - // | REFRESH | 0 | - // | PRECHARGE | 1 | - // | ACTIVATE | 2 | - // | READ | 3 | - // | WRITE | 4 | - // | SELF REFRESH ENTER | 5 | - // | SELF REFRESH EXIT | 6 | - // | UNKNOWN | 7 | - // +-----------------------+---------+ - // - // Use a small packed reg to avoid wide string literal assignments - // and the associated WIDTHEXPAND warnings. - reg [2:0] reqType; // holds 0..7 per table above + // String register (max 16 chars wide here) + reg [8*16-1:0] opString; initial begin - $sformat(filename, "memory_request_queue_stats_scheduler_channel%0d_rank%0d_bank%0d.csv", CHANNEL, RANK, BANK); + $sformat(filename, + "memory_request_queue_stats_scheduler_channel%0d_rank%0d_bank%0d.csv", + CHANNEL, RANK, BANK); file = $fopen(filename, "w"); - $fwrite(file, "RequestID,InternalReqID,ChannelID,RankID,BankID,SchedulerID,Address,Data,TypeID,Cycle\n"); + $fwrite(file, + "RequestID,InternalReqID,ChannelID,RankID,BankID,SchedulerID,Address,Data,Op,Cycle\n"); end always @(posedge clk) begin if (!reset && req_fire) begin - // Encode DRAM command type as a small integer ID - if (cs == 0 && ras == 0 && cas == 0 && we == 1) - reqType = 0; // REFRESH - else if (cs == 0 && ras == 0 && cas == 1 && we == 0) - reqType = 1; // PRECHARGE - else if (cs == 0 && ras == 0 && cas == 1 && we == 1) - reqType = 2; // ACTIVATE - else if (cs == 0 && ras == 1 && cas == 0 && we == 1) - reqType = 3; // READ - else if (cs == 0 && ras == 1 && cas == 0 && we == 0) - reqType = 4; // WRITE - else if (cs == 0 && ras == 0 && cas == 0 && we == 0) - reqType = 5; // SELF REFRESH ENTER - else if (cs == 0 && ras == 1 && cas == 1 && we == 1) - reqType = 6; // SELF REFRESH EXIT - else - reqType = 7; // UNKNOWN + // Map op code to string name + case (op) + 0: opString = "ACTIVATE"; + 1: opString = "READ"; + 2: opString = "WRITE"; + 3: opString = "READ_PRECHARGE"; + 4: opString = "WRITE_PRECHARGE"; + 5: opString = "PRECHARGE"; + 6: opString = "REFRESH"; + 7: opString = "SELFREF_ENTER"; + 8: opString = "SELFREF_EXIT"; + default: opString = "UNKNOWN"; + endcase - // Log CSV with numeric type ID (avoids wide string assignments) - // Fields: RequestID,InternalReqID,ChannelID,RankID,BankID,SchedulerID,Address,Data,TypeID,Cycle - $fwrite(file, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", + // Log CSV with string field + $fwrite(file, "%0d,%0d,%0d,%0d,%0d,%0d,%0h,%0h,%s,%0d\n", request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, data, reqType, globalCycle); + addr, data, opString, globalCycle); end end endmodule diff --git a/memorysim/memctrl/src/main/resources/vsrc/CommandQueuePerformanceStatisticsInput.sv b/memorysim/memctrl/src/main/resources/vsrc/CommandQueuePerformanceStatisticsInput.sv index 6dd2ec7..0232471 100644 --- a/memorysim/memctrl/src/main/resources/vsrc/CommandQueuePerformanceStatisticsInput.sv +++ b/memorysim/memctrl/src/main/resources/vsrc/CommandQueuePerformanceStatisticsInput.sv @@ -9,10 +9,7 @@ module CommandQueuePerformanceStatisticsInput #( input wire req_fire, input wire [ADDRESS_WIDTH-1:0] addr, input wire [DATA_WIDTH-1:0] data, - input wire cs, - input wire ras, - input wire cas, - input wire we, + input wire [DATA_WIDTH-1:0] op, // DRAMOp enum encoding input wire [GLOBAL_CYCLE_BITS-1:0] globalCycle, input wire [REQUEST_ID_BITS-1:0] request_id, input wire [REQUEST_ID_BITS-1:0] internal_req_id, @@ -22,6 +19,8 @@ module CommandQueuePerformanceStatisticsInput #( input wire [REQUEST_ID_BITS-1:0] scheduler_id ); integer file; + reg [8*24-1:0] opString; // wide enough to hold longest name + initial begin file = $fopen("memory_request_queue_stats.csv", "w"); $fwrite(file, "RequestID,InternalReqID,Channel,Rank,Bank,Scheduler,Address,Type,Cycle\n"); @@ -29,41 +28,24 @@ module CommandQueuePerformanceStatisticsInput #( always @(posedge clk) begin if (!reset && req_fire) begin - if(cs == 0 && ras == 0 && cas == 0 && we == 1) begin - $fwrite(file, "%0d,%0d,%0d,%0d,%0d,%0d,%0d,%s,%0d\n", - request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, "REFRESH", globalCycle); - end - else if(cs == 0 && ras == 0 && cas == 1 && we == 0) begin - $fwrite(file, "%0d,%0d,%0d,%0d,%0d,%0d,%0d,%s,%0d\n", - request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, "PRECHARGE", globalCycle); - end - else if(cs == 0 && ras == 0 && cas == 1 && we == 1) begin - $fwrite(file, "%0d,%0d,%0d,%0d,%0d,%0d,%0d,%s,%0d\n", - request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, "ACTIVATE", globalCycle); - end - else if(cs == 0 && ras == 1 && cas == 0 && we == 1) begin - $fwrite(file, "%0d,%0d,%0d,%0d,%0d,%0d,%0d,%s,%0d\n", - request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, "READ", globalCycle); - end - else if(cs == 0 && ras == 1 && cas == 0 && we == 0) begin - $fwrite(file, "%0d,%0d,%0d,%0d,%0d,%0d,%0d,%s,%0d\n", - request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, "WRITE", globalCycle); - end - else if(cs == 0 && ras == 0 && cas == 0 && we == 0) begin - $fwrite(file, "%0d,%0d,%0d,%0d,%0d,%0d,%0d,%s,%0d\n", - request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, "SELF REFRESH ENTER", globalCycle); - end - else if(cs == 0 && ras == 1 && cas == 1 && we == 1) begin - $fwrite(file, "%0d,%0d,%0d,%0d,%0d,%0d,%0d,%s,%0d\n", - request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, - addr, "SELF REFRESH EXIT", globalCycle); - end + // Map op enum to human-readable string + case (op) + 0: opString = "ACTIVATE"; + 1: opString = "READ"; + 2: opString = "WRITE"; + 3: opString = "READ_PRECHARGE"; + 4: opString = "WRITE_PRECHARGE"; + 5: opString = "PRECHARGE"; + 6: opString = "REFRESH"; + 7: opString = "SELFREF_ENTER"; + 8: opString = "SELFREF_EXIT"; + default: opString = "UNKNOWN"; + endcase + + // Log CSV with string op + $fwrite(file, "%0d,%0d,%0d,%0d,%0d,%0d,%0h,%s,%0d\n", + request_id, internal_req_id, channel_id, rank_id, bank_id, scheduler_id, + addr, opString, globalCycle); end end endmodule diff --git a/memorysim/memctrl/src/main/resources/vsrc/SystemQueuePerformanceStatisticsInput.sv b/memorysim/memctrl/src/main/resources/vsrc/SystemQueuePerformanceStatisticsInput.sv index ff332b1..31e2a4a 100644 --- a/memorysim/memctrl/src/main/resources/vsrc/SystemQueuePerformanceStatisticsInput.sv +++ b/memorysim/memctrl/src/main/resources/vsrc/SystemQueuePerformanceStatisticsInput.sv @@ -18,7 +18,6 @@ module SystemQueuePerformanceStatisticsInput #( initial begin file = $fopen("input_request_stats.csv", "w"); $fwrite(file, "RequestID,Address,Read,Write,Cycle,Write Data\n"); - $display("IN VERILOG INPUT"); end diff --git a/memorysim/memctrl/src/main/resources/vsrc/SystemQueuePerformanceStatisticsOutput.sv b/memorysim/memctrl/src/main/resources/vsrc/SystemQueuePerformanceStatisticsOutput.sv index a8d5378..c094f44 100644 --- a/memorysim/memctrl/src/main/resources/vsrc/SystemQueuePerformanceStatisticsOutput.sv +++ b/memorysim/memctrl/src/main/resources/vsrc/SystemQueuePerformanceStatisticsOutput.sv @@ -19,7 +19,6 @@ module SystemQueuePerformanceStatisticsOutput #( initial begin file = $fopen("output_request_stats.csv", "w"); $fwrite(file, "RequestID,Address,Read,Write,Cycle, Write Data,Response\n"); - $display("IN VERILOG OUTPUT"); end diff --git a/memorysim/memctrl/src/main/scala/memorysim/memctrl/controller/schedulers/ClosedPageBankScheduler.scala b/memorysim/memctrl/src/main/scala/memorysim/memctrl/controller/schedulers/ClosedPageBankScheduler.scala index f0cc36a..7a290b2 100644 --- a/memorysim/memctrl/src/main/scala/memorysim/memctrl/controller/schedulers/ClosedPageBankScheduler.scala +++ b/memorysim/memctrl/src/main/scala/memorysim/memctrl/controller/schedulers/ClosedPageBankScheduler.scala @@ -92,20 +92,17 @@ class ClosedPageBankScheduler( // Default command fields cmdReg.addr := reqAddrReg cmdReg.data := reqWdataReg - cmdReg.cs := true.B - cmdReg.ras := false.B - cmdReg.cas := false.B - cmdReg.we := false.B + cmdReg.op := DRAMOp.ACTIVATE // Default, will be overridden cmdReg.request_id := activateReqPacket // Default, will be overridden io.cmdOut.bits := cmdReg // Issue commands when in command states and haven't sent yet val issueStates = Seq(sActivate, sReadWrite, sRefresh) - io.cmdOut.valid := issueStates.map(_ === state).reduce(_ || _) && !sentCmd && !cmdReg.cs + io.cmdOut.valid := issueStates.map(_ === state).reduce(_ || _) && !sentCmd // Response data wire val responseDataWire = Wire(UInt(memoryConfig.dataWidth.W)) - responseDataWire := Mux(reqIsRead, responseDataReg, 0.U) + responseDataWire := responseDataReg val respReg = Wire(new ControllerResponse(memoryConfig)) respReg.addr := reqAddrReg @@ -155,11 +152,8 @@ class ClosedPageBankScheduler( is(sActivate) { when(!sentCmd) { - // Send ACTIVATE command with internal_req_id = 1 - cmdReg.cs := false.B - cmdReg.ras := false.B - cmdReg.cas := true.B - cmdReg.we := true.B + // Send ACTIVATE command + cmdReg.op := DRAMOp.ACTIVATE cmdReg.request_id := activateReqPacket } when(io.cmdOut.fire) { @@ -173,11 +167,8 @@ class ClosedPageBankScheduler( is(sReadWrite) { when(!sentCmd) { - // Send READ or WRITE command with internal_req_id = 2 or 3 - cmdReg.cs := false.B - cmdReg.ras := true.B - cmdReg.cas := false.B - cmdReg.we := Mux(reqIsRead, true.B, false.B) + // Send READ or WRITE command + cmdReg.op := Mux(reqIsRead, DRAMOp.READ, DRAMOp.WRITE) cmdReg.request_id := readWriteReqPacket } when(io.cmdOut.fire) { @@ -208,11 +199,8 @@ class ClosedPageBankScheduler( is(sRefresh) { when(!sentCmd) { - // Send REFRESH command with internal_req_id = refreshCounter - cmdReg.cs := false.B - cmdReg.ras := false.B - cmdReg.cas := false.B - cmdReg.we := true.B + // Send REFRESH command + cmdReg.op := DRAMOp.REFRESH cmdReg.addr := refreshAddr cmdReg.request_id := refreshReqPacket } @@ -251,4 +239,4 @@ class ClosedPageBankScheduler( ) && (respDec.io.rankIndex === localConfiguration.rankIndex.U) && (respDec.io.bankIndex === localConfiguration.bankIndex.U) -} +} \ No newline at end of file diff --git a/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/PhysicalMemoryGenerics.scala b/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/PhysicalMemoryGenerics.scala index 175e683..e6a2ec7 100644 --- a/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/PhysicalMemoryGenerics.scala +++ b/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/PhysicalMemoryGenerics.scala @@ -17,10 +17,7 @@ class RequestPacket(params: MemoryConfigurationParameters) extends Bundle { class PhysicalMemoryCommand(params: MemoryConfigurationParameters) extends Bundle { val addr = UInt(params.addressWidth.W) val data = UInt(params.dataWidth.W) - val cs = Bool() - val ras = Bool() - val cas = Bool() - val we = Bool() + val op = UInt(params.dataWidth.W) // Encoded DRAM operation val request_id = new RequestPacket(params) } @@ -48,10 +45,7 @@ class PhysicalMemoryIO(params: MemoryConfigurationParameters) extends Bundle { class BankMemoryCommand(params: MemoryConfigurationParameters) extends Bundle { val addr = UInt(params.addressWidth.W) val data = UInt(params.dataWidth.W) - val cs = Bool() - val ras = Bool() - val cas = Bool() - val we = Bool() + val op = UInt(params.dataWidth.W) // Encoded DRAM operation val request_id = new RequestPacket(params) val lastColBankGroup = UInt(32.W) val lastColCycle = UInt(32.W) diff --git a/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/Rank.scala b/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/Rank.scala index 595a5cf..8b0495c 100644 --- a/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/Rank.scala +++ b/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/Rank.scala @@ -35,7 +35,7 @@ class Rank( val banksWithTiming = Seq.tabulate(params.numberOfBanks) { idx => val cfg = localConfig.copy(bankIndex = idx) val bank = Module(new DRAMBankWithWait(bankParams, params, cfg, trackPerformance)) - val timer = Module(new SingleCycleTimingEngine(bankParams, params, cfg)) + val timer = Module(new TimingEngine(bankParams, params, cfg)) val deqPort = cmdDemux.io.deq(idx) // Create BankMemoryCommand with metadata @@ -48,10 +48,7 @@ class Rank( // Fill in the command fields stamped.bits.addr := deqPort.bits.addr stamped.bits.data := deqPort.bits.data - stamped.bits.cs := deqPort.bits.cs - stamped.bits.ras := deqPort.bits.ras - stamped.bits.cas := deqPort.bits.cas - stamped.bits.we := deqPort.bits.we + stamped.bits.op := deqPort.bits.op stamped.bits.request_id := deqPort.bits.request_id stamped.bits.lastColBankGroup := lastColBank stamped.bits.lastColCycle := lastColCycle diff --git a/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/BankModel.scala b/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/BankModel.scala index 06367fc..020bb3d 100644 --- a/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/BankModel.scala +++ b/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/BankModel.scala @@ -45,19 +45,14 @@ class DRAMBankWithWait( val mem = Mem(params.addressSpaceSize, UInt(memConfig.dataWidth.W)) // loadMemoryFromFile(mem, "/workspace/chipyard/generators/memorysim/zero_init.hex") - // decode bits from pending - val cs_p = !pending.cs - val ras_p = !pending.ras - val cas_p = !pending.cas - val we_p = !pending.we - - val doActivate = cs_p && ras_p && !cas_p && !we_p - val doRead = cs_p && !ras_p && cas_p && !we_p - val doWrite = cs_p && !ras_p && cas_p && we_p - val doPrecharge = cs_p && ras_p && !cas_p && we_p - val doRefresh = cs_p && ras_p && cas_p && !we_p - val doSrefEnter = cs_p && ras_p && cas_p && we_p - val doSrefExit = cs_p && !ras_p && !cas_p && !we_p + // decode operation from pending.op + val doActivate = pending.op === DRAMOp.ACTIVATE + val doRead = pending.op === DRAMOp.READ + val doWrite = pending.op === DRAMOp.WRITE + val doPrecharge = pending.op === DRAMOp.PRECHARGE + val doRefresh = pending.op === DRAMOp.REFRESH + val doSrefEnter = pending.op === DRAMOp.SREF_ENTER + val doSrefExit = pending.op === DRAMOp.SREF_EXIT // instantiate AddressDecoder for row/column private val addrDecoder = Module(new AddressDecoder(memConfig, params)) @@ -163,4 +158,4 @@ class DRAMBankWithWait( perf.io.active_row := reqRow perf.io.active_col := reqCol } -} +} \ No newline at end of file diff --git a/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/BankOperations.scala b/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/BankOperations.scala index dffd22f..652f376 100644 --- a/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/BankOperations.scala +++ b/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/BankOperations.scala @@ -4,15 +4,17 @@ import chisel3._ import chisel3.util._ object DRAMOp { - val ACTIVATE = 0.U(3.W) - val READ = 1.U(3.W) - val WRITE = 2.U(3.W) - val READ_PRECHARGE = 3.U(3.W) - val WRITE_PRECHARGE = 4.U(3.W) - val PRECHARGE = 5.U(3.W) - val REFRESH = 6.U(3.W) - val SREF_ENTER = 7.U(3.W) - val N_OPS = 8 + val ACTIVATE = 0.U(4.W) + val READ = 1.U(4.W) + val WRITE = 2.U(4.W) + val READ_PRECHARGE = 3.U(4.W) + val WRITE_PRECHARGE = 4.U(4.W) + val PRECHARGE = 5.U(4.W) + val REFRESH = 6.U(4.W) + val SREF_ENTER = 7.U(4.W) + val SREF_EXIT = 8.U(4.W) + val INVALID_OP = 15.U(4.W) + val N_OPS = 16 // For now, we'll just set this to a convenient power of two. This isn't REALLY the number of operations. // Scala ints for matching val ACTIVATE_INT = 0 val READ_INT = 1 @@ -21,5 +23,6 @@ object DRAMOp { val WP_INT = 4 val PRE_INT = 5 val REF_INT = 6 - val SREF_INT = 7 + val SREF_ENTER_INT = 7 + val SREF_EXIT_INT = 8 } diff --git a/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/timing/BankTiming.scala b/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/timing/BankTiming.scala index f791a9b..b7a2d0d 100644 --- a/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/timing/BankTiming.scala +++ b/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/timing/BankTiming.scala @@ -10,46 +10,29 @@ class TimingEngine( extends Module { val io = IO(new Bundle { val cmd = Flipped(Decoupled(new BankMemoryCommand(memConfig))) - val waitCycles = Output(UInt(32.W)) + val waitCycles = Output(UInt(memConfig.globalCycleCountBits.W)) }) // Prev/Cur ops - val prevOp = RegInit(DRAMOp.N_OPS.U) - // Decode incoming command into DRAMOp - val cs_p = Wire(Bool()); cs_p := !io.cmd.bits.cs - val ras_p = Wire(Bool()); ras_p := !io.cmd.bits.ras - val cas_p = Wire(Bool()); cas_p := !io.cmd.bits.cas - val we_p = Wire(Bool()); we_p := !io.cmd.bits.we - - val currOp = Wire(UInt(3.W)) - currOp := DRAMOp.N_OPS.U // default invalid op - - switch(Cat(cs_p, ras_p, cas_p, we_p)) { - is("b1100".U) { currOp := DRAMOp.ACTIVATE } // cs=1 ras=1 cas=0 we=0 - is("b1010".U) { currOp := DRAMOp.READ } // cs=1 ras=0 cas=1 we=0 - is("b1011".U) { currOp := DRAMOp.WRITE } // cs=1 ras=0 cas=1 we=1 - is("b1101".U) { currOp := DRAMOp.PRECHARGE } // cs=1 ras=1 cas=0 we=1 - is("b1110".U) { currOp := DRAMOp.REFRESH } // cs=1 ras=1 cas=1 we=0 - is("b1111".U) { currOp := DRAMOp.SREF_ENTER } // cs=1 ras=1 cas=1 we=1 + val INVALID_OP = DRAMOp.INVALID_OP + val prevOp = RegInit(INVALID_OP) + + // Directly use op field from command + val currOp = WireDefault(INVALID_OP) + when(io.cmd.valid) { + currOp := io.cmd.bits.op } - // When a new command fires, shift curr->prev and decode new opcode when(io.cmd.fire) { if (localConfig.verbose) { - printf( - "Received command - cs = %d ras = %d cas = %d we = %d\n", - io.cmd.bits.cs, - io.cmd.bits.ras, - io.cmd.bits.cas, - io.cmd.bits.we - ) + printf("Received command - op = %d\n", io.cmd.bits.op) printf("Prev = %d, Cur = %d Wait = %d\n", prevOp, currOp, io.waitCycles) } prevOp := currOp } // ---------------------------------------------------------------- - // 1) All same‑bank delays as functions of base params + // 1) Base DRAM timing params // ---------------------------------------------------------------- val burst = params.burst_cycle.U(32.W) val tCCD_L = params.tCCD_L.U(32.W) @@ -70,7 +53,7 @@ class TimingEngine( val tRTP_S = params.tRTP_S.U(32.W) val tXS = params.tXS.U(32.W) - // Derived delays: + // Derived delays val read_to_read_l = Mux(burst > tCCD_L, burst, tCCD_L) val read_to_write = RL + burst - WL + tRTRS val read_to_precharge = AL + tRTP @@ -91,7 +74,7 @@ class TimingEngine( val refresh_to_activate = tRFC // ---------------------------------------------------------------- - // 2) same‑bank timing matrix + // 2) same-bank timing matrix with new SREF ops // ---------------------------------------------------------------- val timing = VecInit(Seq.tabulate(DRAMOp.N_OPS) { i => VecInit(Seq.tabulate(DRAMOp.N_OPS) { j => @@ -108,27 +91,30 @@ class TimingEngine( case (DRAMOp.WRITE_INT, DRAMOp.RP_INT) => write_to_read_l case (DRAMOp.WRITE_INT, DRAMOp.WP_INT) => write_to_write_l - case (DRAMOp.RP_INT, DRAMOp.ACTIVATE_INT) => readp_to_activate - case (DRAMOp.RP_INT, DRAMOp.REF_INT) => readp_to_activate - case (DRAMOp.RP_INT, DRAMOp.SREF_INT) => readp_to_activate + case (DRAMOp.RP_INT, DRAMOp.ACTIVATE_INT) => readp_to_activate + case (DRAMOp.RP_INT, DRAMOp.REF_INT) => readp_to_activate + case (DRAMOp.RP_INT, DRAMOp.SREF_ENTER_INT) => readp_to_activate - case (DRAMOp.WP_INT, DRAMOp.ACTIVATE_INT) => writep_to_activate - case (DRAMOp.WP_INT, DRAMOp.REF_INT) => writep_to_activate - case (DRAMOp.WP_INT, DRAMOp.SREF_INT) => writep_to_activate + case (DRAMOp.WP_INT, DRAMOp.ACTIVATE_INT) => writep_to_activate + case (DRAMOp.WP_INT, DRAMOp.REF_INT) => writep_to_activate + case (DRAMOp.WP_INT, DRAMOp.SREF_ENTER_INT) => writep_to_activate case (DRAMOp.ACTIVATE_INT, DRAMOp.ACTIVATE_INT) => activate_to_act_l case (DRAMOp.ACTIVATE_INT, DRAMOp.READ_INT) => activate_to_read case (DRAMOp.ACTIVATE_INT, DRAMOp.WRITE_INT) => activate_to_write case (DRAMOp.ACTIVATE_INT, DRAMOp.PRE_INT) => activate_to_precharge - case (DRAMOp.PRE_INT, DRAMOp.ACTIVATE_INT) => precharge_to_activate - case (DRAMOp.PRE_INT, DRAMOp.REF_INT) => precharge_to_activate - case (DRAMOp.PRE_INT, DRAMOp.SREF_INT) => precharge_to_activate + case (DRAMOp.PRE_INT, DRAMOp.ACTIVATE_INT) => precharge_to_activate + case (DRAMOp.PRE_INT, DRAMOp.REF_INT) => precharge_to_activate + case (DRAMOp.PRE_INT, DRAMOp.SREF_ENTER_INT) => precharge_to_activate - case (DRAMOp.REF_INT, DRAMOp.ACTIVATE_INT) => refresh_to_activate - case (DRAMOp.REF_INT, DRAMOp.SREF_INT) => refresh_to_activate + case (DRAMOp.REF_INT, DRAMOp.ACTIVATE_INT) => refresh_to_activate + case (DRAMOp.REF_INT, DRAMOp.SREF_ENTER_INT) => refresh_to_activate - case (DRAMOp.SREF_INT, DRAMOp.SREF_INT) => tXS + case (DRAMOp.SREF_ENTER_INT, DRAMOp.SREF_ENTER_INT) => tXS + case (DRAMOp.SREF_EXIT_INT, DRAMOp.ACTIVATE_INT) => tXS + case (DRAMOp.SREF_EXIT_INT, DRAMOp.READ_INT) => tXS + case (DRAMOp.SREF_EXIT_INT, DRAMOp.WRITE_INT) => tXS case _ => 1.U(32.W) } @@ -138,7 +124,7 @@ class TimingEngine( // ---------------------------------------------------------------- // 3) Final lookup // ---------------------------------------------------------------- - when(prevOp === DRAMOp.N_OPS.U || currOp === DRAMOp.N_OPS.U) { + when(prevOp === INVALID_OP || currOp === INVALID_OP) { io.waitCycles := 0.U }.otherwise { io.waitCycles := timing(prevOp)(currOp) diff --git a/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/timing/SingleCycleBankTiming.scala b/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/timing/SingleCycleBankTiming.scala index 275cae0..7e2bad5 100644 --- a/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/timing/SingleCycleBankTiming.scala +++ b/memorysim/memctrl/src/main/scala/memorysim/memctrl/memories/bank/timing/SingleCycleBankTiming.scala @@ -10,39 +10,26 @@ class SingleCycleTimingEngine( extends Module { val io = IO(new Bundle { val cmd = Flipped(Decoupled(new BankMemoryCommand(memConfig))) - val waitCycles = Output(UInt(32.W)) + val waitCycles = Output(UInt(memConfig.globalCycleCountBits.W)) }) - // Prev/Cur ops - val prevOp = RegInit(DRAMOp.N_OPS.U) - // Decode incoming command into DRAMOp - val cs_p = Wire(Bool()); cs_p := !io.cmd.bits.cs - val ras_p = Wire(Bool()); ras_p := !io.cmd.bits.ras - val cas_p = Wire(Bool()); cas_p := !io.cmd.bits.cas - val we_p = Wire(Bool()); we_p := !io.cmd.bits.we - - val currOp = Wire(UInt(3.W)) - currOp := DRAMOp.N_OPS.U // default invalid op - - switch(Cat(cs_p, ras_p, cas_p, we_p)) { - is("b1100".U) { currOp := DRAMOp.ACTIVATE } // cs=1 ras=1 cas=0 we=0 - is("b1010".U) { currOp := DRAMOp.READ } // cs=1 ras=0 cas=1 we=0 - is("b1011".U) { currOp := DRAMOp.WRITE } // cs=1 ras=0 cas=1 we=1 - is("b1101".U) { currOp := DRAMOp.PRECHARGE } // cs=1 ras=1 cas=0 we=1 - is("b1110".U) { currOp := DRAMOp.REFRESH } // cs=1 ras=1 cas=1 we=0 - is("b1111".U) { currOp := DRAMOp.SREF_ENTER } // cs=1 ras=1 cas=1 we=1 + // Prev/Cur ops (4-bit to match DRAMOp.* widths) + val INVALID_OP = DRAMOp.INVALID_OP + val prevOp = RegInit(INVALID_OP) + + // Use op field directly (assume lower 4 bits encode DRAMOp) + val currOp = Wire(UInt(memConfig.dataWidth.W)) + currOp := INVALID_OP // default invalid op + when(io.cmd.valid) { + // safely grab low 4 bits of op (in case width differs) + currOp := io.cmd.bits.op + } - // When a new command fires, shift curr->prev and decode new opcode + // When a new command fires, shift curr->prev when(io.cmd.fire) { if (localConfig.verbose) { - printf( - "Received command - cs = %d ras = %d cas = %d we = %d\n", - io.cmd.bits.cs, - io.cmd.bits.ras, - io.cmd.bits.cas, - io.cmd.bits.we - ) + printf("Received command - op = %d\n", io.cmd.bits.op(3,0)) printf("Prev = %d, Cur = %d Wait = %d\n", prevOp, currOp, io.waitCycles) } prevOp := currOp @@ -71,7 +58,7 @@ class SingleCycleTimingEngine( val refresh_to_activate = 1.U(32.W) // ---------------------------------------------------------------- - // 2) same‑bank timing matrix + // 2) same-bank timing matrix // ---------------------------------------------------------------- val timing = VecInit(Seq.tabulate(DRAMOp.N_OPS) { i => VecInit(Seq.tabulate(DRAMOp.N_OPS) { j => @@ -90,11 +77,13 @@ class SingleCycleTimingEngine( case (DRAMOp.RP_INT, DRAMOp.ACTIVATE_INT) => readp_to_activate case (DRAMOp.RP_INT, DRAMOp.REF_INT) => readp_to_activate - case (DRAMOp.RP_INT, DRAMOp.SREF_INT) => readp_to_activate + // RP -> SREF_ENTER (kept behavior similar to before) + case (DRAMOp.RP_INT, DRAMOp.SREF_ENTER_INT) => readp_to_activate case (DRAMOp.WP_INT, DRAMOp.ACTIVATE_INT) => writep_to_activate case (DRAMOp.WP_INT, DRAMOp.REF_INT) => writep_to_activate - case (DRAMOp.WP_INT, DRAMOp.SREF_INT) => writep_to_activate + // WP -> SREF_ENTER + case (DRAMOp.WP_INT, DRAMOp.SREF_ENTER_INT) => writep_to_activate case (DRAMOp.ACTIVATE_INT, DRAMOp.ACTIVATE_INT) => activate_to_act_l case (DRAMOp.ACTIVATE_INT, DRAMOp.READ_INT) => activate_to_read @@ -103,12 +92,13 @@ class SingleCycleTimingEngine( case (DRAMOp.PRE_INT, DRAMOp.ACTIVATE_INT) => precharge_to_activate case (DRAMOp.PRE_INT, DRAMOp.REF_INT) => precharge_to_activate - case (DRAMOp.PRE_INT, DRAMOp.SREF_INT) => precharge_to_activate + case (DRAMOp.PRE_INT, DRAMOp.SREF_ENTER_INT) => precharge_to_activate case (DRAMOp.REF_INT, DRAMOp.ACTIVATE_INT) => refresh_to_activate - case (DRAMOp.REF_INT, DRAMOp.SREF_INT) => refresh_to_activate + case (DRAMOp.REF_INT, DRAMOp.SREF_ENTER_INT) => refresh_to_activate - case (DRAMOp.SREF_INT, DRAMOp.SREF_INT) => tXS + // SREF_ENTER staying in SREF_ENTER -> tXS + case (DRAMOp.SREF_ENTER_INT, DRAMOp.SREF_ENTER_INT) => tXS case _ => 1.U(32.W) } @@ -118,9 +108,11 @@ class SingleCycleTimingEngine( // ---------------------------------------------------------------- // 3) Final lookup // ---------------------------------------------------------------- - when(prevOp === DRAMOp.N_OPS.U || currOp === DRAMOp.N_OPS.U) { + when(prevOp === INVALID_OP || currOp === INVALID_OP) { io.waitCycles := 0.U }.otherwise { + // prevOp and currOp are 4-bit UInts; timing expects Int indices + // use .asUInt for indexing (Vec index will accept UInt that fits) io.waitCycles := timing(prevOp)(currOp) } diff --git a/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/BankPerformanceStatistics.scala b/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/BankPerformanceStatistics.scala index 787c4fa..c3bce93 100644 --- a/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/BankPerformanceStatistics.scala +++ b/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/BankPerformanceStatistics.scala @@ -35,10 +35,7 @@ class BankPhysicalMemoryRequestPerformanceStatistics( val req_fire = Input(Bool()) val addr = Input(UInt(memParams.addressWidth.W)) val data = Input(UInt(memParams.dataWidth.W)) - val cs = Input(Bool()) - val ras = Input(Bool()) - val cas = Input(Bool()) - val we = Input(Bool()) + val op = Input(UInt(memParams.dataWidth.W)) val globalCycle = Input(UInt(memParams.globalCycleCountBits.W)) val request_id = Input(UInt(memParams.requestIDBits.W)) val internal_req_id = Input(UInt(memParams.requestIDBits.W)) @@ -142,10 +139,7 @@ class BankPerformanceStatistics(localConfiguration: LocalConfigurationParameters perfMemRequests.io.req_fire := io.mem_request_fire perfMemRequests.io.addr := io.mem_request_bits.addr perfMemRequests.io.data := io.mem_request_bits.data - perfMemRequests.io.cs := io.mem_request_bits.cs - perfMemRequests.io.ras := io.mem_request_bits.ras - perfMemRequests.io.cas := io.mem_request_bits.cas - perfMemRequests.io.we := io.mem_request_bits.we + perfMemRequests.io.op := io.mem_request_bits.op perfMemRequests.io.request_id := io.mem_request_bits.request_id.request_id perfMemRequests.io.internal_req_id := io.mem_request_bits.request_id.internal_req_id perfMemRequests.io.channel_id := io.mem_request_bits.request_id.channel_id diff --git a/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/CommandQueuePerformanceStatistics.scala b/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/CommandQueuePerformanceStatistics.scala index 027ce7c..0328d4f 100644 --- a/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/CommandQueuePerformanceStatistics.scala +++ b/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/CommandQueuePerformanceStatistics.scala @@ -28,10 +28,7 @@ class CommandQueuePerformanceStatisticsInput(val memParams: MemoryConfigurationP val req_fire = Input(Bool()) val addr = Input(UInt(memParams.addressWidth.W)) val data = Input(UInt(memParams.dataWidth.W)) - val cs = Input(Bool()) - val ras = Input(Bool()) - val cas = Input(Bool()) - val we = Input(Bool()) + val op = Input(UInt(memParams.dataWidth.W)) val globalCycle = Input(UInt(memParams.globalCycleCountBits.W)) val request_id = Input(UInt(memParams.requestIDBits.W)) val internal_req_id = Input(UInt(memParams.requestIDBits.W)) @@ -112,10 +109,7 @@ class CommandQueuePerformanceStatistics(params: MemoryConfigurationParameters) e perfIn.io.req_fire := io.in_fire perfIn.io.addr := io.in_bits.addr perfIn.io.data := io.in_bits.data - perfIn.io.cs := io.in_bits.cs - perfIn.io.ras := io.in_bits.ras - perfIn.io.cas := io.in_bits.cas - perfIn.io.we := io.in_bits.we + perfIn.io.op := io.in_bits.op perfIn.io.request_id := io.in_bits.request_id.request_id perfIn.io.internal_req_id := io.in_bits.request_id.internal_req_id perfIn.io.channel_id := io.in_bits.request_id.channel_id diff --git a/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/SchedulerMemoryPerformanceStatistics.scala b/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/SchedulerMemoryPerformanceStatistics.scala index f64f9ba..044f8c4 100644 --- a/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/SchedulerMemoryPerformanceStatistics.scala +++ b/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/SchedulerMemoryPerformanceStatistics.scala @@ -35,10 +35,7 @@ class BankSchedulerPhysicalMemoryRequestPerformanceStatistics( val req_fire = Input(Bool()) val addr = Input(UInt(memParams.addressWidth.W)) val data = Input(UInt(memParams.dataWidth.W)) - val cs = Input(Bool()) - val ras = Input(Bool()) - val cas = Input(Bool()) - val we = Input(Bool()) + val op = Input(UInt(memParams.dataWidth.W)) val globalCycle = Input(UInt(memParams.globalCycleCountBits.W)) val request_id = Input(UInt(memParams.requestIDBits.W)) val internal_req_id = Input(UInt(memParams.requestIDBits.W)) diff --git a/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/SchedulerPerformanceStatistics.scala b/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/SchedulerPerformanceStatistics.scala index ab00952..9870e13 100644 --- a/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/SchedulerPerformanceStatistics.scala +++ b/memorysim/memctrl/src/main/scala/memorysim/memctrl/utils/trackers/SchedulerPerformanceStatistics.scala @@ -140,12 +140,6 @@ class BankSchedulerPerformanceStatistics( ) ) - // // Connect clock and reset - // Seq(perfIn.io, perfOut.io, perfMemRequests.io, perfMemResponses.io).foreach { bb => - // bbi.clk := io.clk - // bbi.reset := io.reset.asBool - // } - /* Request / Response Interface */ // Connect input request logging perfIn.io.clk := clock @@ -175,10 +169,7 @@ class BankSchedulerPerformanceStatistics( perfMemRequests.io.req_fire := io.mem_request_fire perfMemRequests.io.addr := io.mem_request_bits.addr perfMemRequests.io.data := io.mem_request_bits.data - perfMemRequests.io.cs := io.mem_request_bits.cs - perfMemRequests.io.ras := io.mem_request_bits.ras - perfMemRequests.io.cas := io.mem_request_bits.cas - perfMemRequests.io.we := io.mem_request_bits.we + perfMemRequests.io.op := io.mem_request_bits.op perfMemRequests.io.request_id := io.mem_request_bits.request_id.request_id perfMemRequests.io.internal_req_id := io.mem_request_bits.request_id.internal_req_id perfMemRequests.io.channel_id := io.mem_request_bits.request_id.channel_id @@ -200,4 +191,4 @@ class BankSchedulerPerformanceStatistics( perfMemResponses.io.bank_id := io.mem_response_bits.request_id.bank_id perfMemResponses.io.scheduler_id := io.mem_response_bits.request_id.scheduler_identifier perfMemResponses.io.globalCycle := cycleCounter -} +} \ No newline at end of file diff --git a/memorysim/memctrl/src/test/scala/memorysim/memctrl/memories/PhysicalMemorySpec.scala b/memorysim/memctrl/src/test/scala/memorysim/memctrl/memories/PhysicalMemorySpec.scala index 0d2bd5f..d42553c 100644 --- a/memorysim/memctrl/src/test/scala/memorysim/memctrl/memories/PhysicalMemorySpec.scala +++ b/memorysim/memctrl/src/test/scala/memorysim/memctrl/memories/PhysicalMemorySpec.scala @@ -1,9 +1,3 @@ -/** Verification Spec Target: - * - * \- Verify, at the functional (input / output) level that Physical memory modules work as desired (i.e, we can issue - * reads and writes) \- Verify that the FSM can drive ANY and ALL Physical DRAM Memory Instances - */ - package memorysim.memctrl import chisel3._ @@ -17,28 +11,28 @@ class PhysicalMemoryModuleSpec extends AnyFreeSpec with Matchers { // ----------------------- // DRAM Flow Test Helpers // ----------------------- + private def sendCmd( dut: PhysicalMemoryModuleBase, addr: UInt, data: UInt, - cs: Boolean, - ras: Boolean, - cas: Boolean, - we: Boolean + op: UInt ): Unit = { dut.io.memCmd.bits.addr.poke(addr) dut.io.memCmd.bits.data.poke(data) - dut.io.memCmd.bits.cs.poke(cs.B) - dut.io.memCmd.bits.ras.poke(ras.B) - dut.io.memCmd.bits.cas.poke(cas.B) - dut.io.memCmd.bits.we.poke(we.B) + dut.io.memCmd.bits.op.poke(op) dut.io.memCmd.valid.poke(true.B) - while (!dut.io.memCmd.ready.peek().litToBoolean) dut.clock.step() + while (!dut.io.memCmd.ready.peek().litToBoolean) { dut.clock.step() } dut.clock.step() dut.io.memCmd.valid.poke(false.B) } - private def expectResp(dut: PhysicalMemoryModuleBase, expAddr: UInt, expData: UInt, maxCycles: Int = 500): Unit = { + private def expectResp( + dut: PhysicalMemoryModuleBase, + expAddr: UInt, + expData: UInt, + maxCycles: Int = 500 + ): Unit = { var cycles = 0 while (!dut.io.phyResp.valid.peek().litToBoolean && cycles < maxCycles) { dut.clock.step(); cycles += 1 @@ -56,25 +50,38 @@ class PhysicalMemoryModuleSpec extends AnyFreeSpec with Matchers { simulate(instantiate) { dut => dut.reset.poke(true.B); dut.clock.step(); dut.reset.poke(false.B); dut.clock.step() dut.io.phyResp.ready.poke(true.B) - val base = 0x10.U; val pat = "hABCD".U - // init read + + val base = 0x10.U + val pat = "hABCD".U println("IN DRAM FLOW SPEC") - sendCmd(dut, base, 0.U, cs = false, ras = false, cas = true, we = true) + + // init ACTIVATE + sendCmd(dut, base, 0.U, DRAMOp.ACTIVATE) + expectResp(dut, base, 0.U) + + // READ (expect default 0) + sendCmd(dut, base, 0.U, DRAMOp.READ) expectResp(dut, base, 0.U) - sendCmd(dut, base, 0.U, cs = false, ras = true, cas = false, we = true) + + // PRECHARGE + sendCmd(dut, base, 0.U, DRAMOp.PRECHARGE) expectResp(dut, base, 0.U) - sendCmd(dut, base, 0.U, cs = false, ras = false, cas = true, we = false) + + // ACTIVATE before WRITE + sendCmd(dut, base, 0.U, DRAMOp.ACTIVATE) expectResp(dut, base, 0.U) - // write pat - sendCmd(dut, base, 0.U, cs = false, ras = false, cas = true, we = true) + + // WRITE pat + sendCmd(dut, base, pat, DRAMOp.WRITE) expectResp(dut, base, 0.U) - sendCmd(dut, base, pat, cs = false, ras = true, cas = false, we = false) - expectResp(dut, base, pat) - sendCmd(dut, base, 0.U, cs = false, ras = false, cas = true, we = false) + + // PRECHARGE again + sendCmd(dut, base, 0.U, DRAMOp.PRECHARGE) expectResp(dut, base, 0.U) - // refresh - sendCmd(dut, base, 0.U, cs = false, ras = false, cas = false, we = true) + + // REFRESH + sendCmd(dut, base, 0.U, DRAMOp.REFRESH) expectResp(dut, base, 0.U) } } @@ -92,7 +99,7 @@ class PhysicalMemoryModuleSpec extends AnyFreeSpec with Matchers { bankIndex = 0 ) - println("[PhysicalMemorySpec] In here. ") + println("[PhysicalMemorySpec] In here.") dramFlowSpec("Channel", new Channel(memParams, bankParams, localConfig)) dramFlowSpec("Rank", new Rank(memParams, bankParams, localConfig)) }