Register reads now working. All functionality is in; need testing, cleanup, merge into master.

This commit is contained in:
rsnikhil
2020-01-15 15:54:50 -05:00
parent 2e909a90a9
commit 16cb92e2c1
3 changed files with 215 additions and 201 deletions

View File

@@ -84,7 +84,18 @@ import Bypass::*;
import CsrFile :: *;
import Cur_Cycle :: *;
// ================================================================
// Toooba
import Cur_Cycle :: *;
import FIFOF :: *;
import GetPut_Aux :: *;
`ifdef INCLUDE_GDB_CONTROL
import DM_CPU_Req_Rsp :: *;
`endif
// ================================================================
`ifdef SECURITY
`define SECURITY_OR_INCLUDE_GDB_CONTROL
@@ -155,14 +166,14 @@ interface Core;
method Action debug_resume;
method Data csr_read (Bit #(12) csr_addr);
method Action csr_write (Bit #(12) csr_addr, Data data);
method Data gpr_read (Bit #(5) gpr_addr);
method Action gpr_write (Bit #(5) gpr_addr, Data data);
interface Server #(DM_CPU_Req #(5, 64), DM_CPU_Rsp #(64)) hart0_gpr_mem_server;
`ifdef ISA_F
method Data fpr_read (Bit #(5) fpr_addr);
method Action fpr_write (Bit #(5) fpr_addr, Data data);
// FPR access
interface Server #(DM_CPU_Req #(5, 64), DM_CPU_Rsp #(64)) hart0_fpr_mem_server;
`endif
// CSR access
interface Server #(DM_CPU_Req #(12, 64), DM_CPU_Rsp #(64)) hart0_csr_mem_server;
`endif
endinterface
@@ -195,7 +206,8 @@ module mkCore#(CoreId coreId)(Core);
Reg#(Bool) started <- mkReg(False);
`ifdef INCLUDE_GDB_CONTROL
Reg #(Core_Run_State) rg_core_run_state <- mkReg (CORE_RUNNING);
// Using a ConfigReg since scheduling of reads/writes not critical (TODO: verify this)
Reg #(Core_Run_State) rg_core_run_state <- mkConfigReg (CORE_RUNNING);
`endif
// front end
@@ -517,6 +529,9 @@ module mkCore#(CoreId coreId)(Core);
`endif
endmethod
method doStats = coreFix.doStatsIfc._read;
`ifdef INCLUDE_GDB_CONTROL
method Bool core_is_running = (rg_core_run_state == CORE_RUNNING);
`endif
endinterface);
RenameStage renameStage <- mkRenameStage(renameInput);
@@ -1012,6 +1027,173 @@ module mkCore#(CoreId coreId)(Core);
endrule
`endif
`ifdef INCLUDE_GDB_CONTROL
// ================================================================
// DEBUG MODULE INTERFACE
// ----------------
// Debug Module GPR read/write
FIFOF #(DM_CPU_Req #(5, 64)) f_gpr_reqs <- mkFIFOF1;
FIFOF #(DM_CPU_Rsp #(64)) f_gpr_rsps <- mkFIFOF1;
rule rl_debug_gpr_read ( (rg_core_run_state == CORE_HALTED)
&& f_gpr_reqs.notEmpty
&& (! f_gpr_reqs.first.write));
let req <- pop (f_gpr_reqs);
Bit #(5) regnum = req.address;
let arch_regs = ArchRegs {src1: tagged Valid (tagged Gpr regnum),
src2: tagged Invalid,
src3: tagged Invalid,
dst: tagged Invalid};
let rename_result = regRenamingTable.rename[0].getRename (arch_regs);
let phy_rindx = fromMaybe (?, rename_result.phy_regs.src1);
let data_out = rf.read [debuggerPort].rd1 (phy_rindx);
let rsp = DM_CPU_Rsp {ok: True, data: data_out};
f_gpr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_read_gpr: reg %0d => 0x%0h", cur_cycle, regnum, data_out);
endrule
rule rl_debug_gpr_write ( (rg_core_run_state == CORE_HALTED)
&& f_gpr_reqs.notEmpty
&& f_gpr_reqs.first.write);
let req <- pop (f_gpr_reqs);
Bit #(5) regnum = req.address;
let data_in = req.data;
let arch_regs = ArchRegs {src1: tagged Valid (tagged Gpr regnum),
src2: tagged Invalid,
src3: tagged Invalid,
dst: tagged Invalid};
let rename_result = regRenamingTable.rename[0].getRename (arch_regs);
let phy_rindx = fromMaybe (?, rename_result.phy_regs.src1);
rf.write [debuggerPort].wr (phy_rindx, data_in);
$display ("%m.gpr_write (%0d, %0x), phy_rindx %0d", regnum, data_in, phy_rindx);
let rsp = DM_CPU_Rsp {ok: True, data: ?};
f_gpr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_write_gpr: reg %0d <= 0x%0h", cur_cycle, regnum, data_in);
endrule
rule rl_debug_gpr_access_busy (rg_core_run_state != CORE_HALTED);
let req <- pop (f_gpr_reqs);
let rsp = DM_CPU_Rsp {ok: False, data: ?};
f_gpr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_gpr_access_busy", cur_cycle);
endrule
`ifdef ISA_F
// ----------------
// Debug Module FPR read/write
FIFOF #(DM_CPU_Req #(5, 64)) f_fpr_reqs <- mkFIFOF1;
FIFOF #(DM_CPU_Rsp #(64)) f_fpr_rsps <- mkFIFOF1;
rule rl_debug_fpr_read ( (rg_core_run_state == CORE_HALTED)
&& (! f_gpr_reqs.notEmpty) // prioritize gpr reqs
&& (! f_fpr_reqs.first.write));
let req <- pop (f_fpr_reqs);
Bit #(5) regnum = req.address;
let arch_regs = ArchRegs {src1: tagged Valid (tagged Fpu regnum),
src2: tagged Invalid,
src3: tagged Invalid,
dst: tagged Invalid};
let rename_result = regRenamingTable.rename[0].getRename (arch_regs);
let phy_rindx = fromMaybe (?, rename_result.phy_regs.src1);
let data_out = rf.read [debuggerPort].rd1 (phy_rindx);
let rsp = DM_CPU_Rsp {ok: True, data: data_out};
f_fpr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_read_fpr: reg %0d => 0x%0h", cur_cycle, regnum, data_out);
endrule
rule rl_debug_fpr_write ( (rg_core_run_state == CORE_HALTED)
&& (! f_gpr_reqs.notEmpty) // prioritize gpr reqs
&& f_fpr_reqs.first.write);
let req <- pop (f_fpr_reqs);
Bit #(5) regnum = req.address;
let data_in = req.data;
let arch_regs = ArchRegs {src1: tagged Valid (tagged Fpu regnum),
src2: tagged Invalid,
src3: tagged Invalid,
dst: tagged Invalid};
let rename_result = regRenamingTable.rename[0].getRename (arch_regs);
let phy_rindx = fromMaybe (?, rename_result.phy_regs.src1);
rf.write [debuggerPort].wr (phy_rindx, data_in);
$display ("%m.gpr_write (%0d, %0x), phy_rindx %0d", regnum, data_in, phy_rindx);
let rsp = DM_CPU_Rsp {ok: True, data: ?};
f_fpr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_write_fpr: reg %0d <= 0x%0h", cur_cycle, regnum, data_in);
endrule
rule rl_debug_fpr_access_busy (rg_core_run_state != CORE_HALTED);
let req <- pop (f_fpr_reqs);
let rsp = DM_CPU_Rsp {ok: False, data: ?};
f_fpr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_fpr_access_busy", cur_cycle);
endrule
`endif
// ----------------
// Debug Module CSR read/write
// Debugger CSR read/write request/response
FIFOF #(DM_CPU_Req #(12, 64)) f_csr_reqs <- mkFIFOF1;
FIFOF #(DM_CPU_Rsp #(64)) f_csr_rsps <- mkFIFOF1;
rule rl_debug_csr_read ( (rg_core_run_state == CORE_HALTED)
&& (! f_csr_reqs.first.write));
let req <- pop (f_csr_reqs);
Bit #(12) csr_addr = req.address;
let data_out = csrf.rd (unpack (csr_addr));
let rsp = DM_CPU_Rsp {ok: True, data: data_out};
f_csr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_read_csr: csr %0d => 0x%0h", cur_cycle, csr_addr, data_out);
endrule
rule rl_debug_csr_write ( (rg_core_run_state == CORE_HALTED)
&& f_csr_reqs.first.write);
let req <- pop (f_csr_reqs);
Bit #(12) csr_addr = req.address;
let data_in = req.data;
csrf.csrInstWr (unpack (csr_addr), data_in);
let rsp = DM_CPU_Rsp {ok: True, data: ?};
f_csr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_write_csr: csr 0x%0h <= 0x%0h", cur_cycle, csr_addr, data_in);
endrule
rule rl_debug_csr_access_busy (rg_core_run_state != CORE_HALTED);
let req <- pop (f_csr_reqs);
let rsp = DM_CPU_Rsp {ok: False, data: ?};
f_csr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_csr_access_busy", cur_cycle);
endrule
// ================================================================
`endif
interface CoreReq coreReq;
method Action start(
Bit#(64) startpc,
@@ -1115,60 +1297,14 @@ module mkCore#(CoreId coreId)(Core);
$display ("%0d: %m.debug_resume, dpc = 0x%0h", cur_cycle, startpc);
endmethod
method Data csr_read (Bit #(12) csr_addr) if (rg_core_run_state == CORE_HALTED);
return csrf.rd (unpack (csr_addr));
endmethod
method Action csr_write (Bit #(12) csr_addr, Data data) if (rg_core_run_state == CORE_HALTED);
csrf.csrInstWr (unpack (csr_addr), data);
endmethod
method Data gpr_read (Bit #(5) gpr_addr) if (rg_core_run_state == CORE_HALTED);
let arch_regs = ArchRegs {src1: tagged Valid (tagged Gpr gpr_addr),
src2: tagged Invalid,
src3: tagged Invalid,
dst: tagged Invalid};
let rename_result = ?; // regRenamingTable.rename[0].getRename (arch_regs);
let phy_rindx = ?; // fromMaybe (?, rename_result.phy_regs.src1);
let data = ?; // rf.read [debuggerPort].rd1 (phy_rindx);
return data;
endmethod
method Action gpr_write (Bit #(5) gpr_addr, Data data) if (rg_core_run_state == CORE_HALTED);
let arch_regs = ArchRegs {src1: tagged Valid (tagged Gpr gpr_addr),
src2: tagged Invalid,
src3: tagged Invalid,
dst: tagged Invalid};
let rename_result = ?; // regRenamingTable.rename[0].getRename (arch_regs);
let phy_rindx = ?; // fromMaybe (?, rename_result.phy_regs.src1);
// rf.write [debuggerPort].wr (phy_rindx, data);
// $display ("%m.gpr_write (%0d, %0x), phy_rindx %0d", gpr_addr, data, phy_rindx);
endmethod
interface Server hart0_gpr_mem_server = toGPServer (f_gpr_reqs, f_gpr_rsps);
`ifdef ISA_F
method Data fpr_read (Bit #(5) fpr_addr) if (rg_core_run_state == CORE_HALTED);
let arch_regs = ArchRegs {src1: tagged Valid (tagged Fpu fpr_addr),
src2: tagged Invalid,
src3: tagged Invalid,
dst: tagged Invalid};
let rename_result = ?; // regRenamingTable.rename[0].getRename (arch_regs);
let phy_rindx = ?; // fromMaybe (?, rename_result.phy_regs.src1);
let data = ?; // rf.read [debuggerPort].rd1 (phy_rindx);
return data;
endmethod
method Action fpr_write (Bit #(5) fpr_addr, Data data) if (rg_core_run_state == CORE_HALTED);
let arch_regs = ArchRegs {src1: tagged Valid (tagged Fpu fpr_addr),
src2: tagged Invalid,
src3: tagged Invalid,
dst: tagged Invalid};
let rename_result = ?; // regRenamingTable.rename[0].getRename (arch_regs);
let phy_rindx = ?; // fromMaybe (?, rename_result.phy_regs.src1);
// rf.write [debuggerPort].wr (phy_rindx, data);
// $display ("%m.fpr_write (%0d, %0x), phy_rindx %0d", fpr_addr, data, phy_rindx);
endmethod
interface Server hart0_fpr_mem_server = toGPServer (f_fpr_reqs, f_fpr_rsps);
`endif
// CSR access
interface Server hart0_csr_mem_server = toGPServer (f_csr_reqs, f_csr_rsps);
`endif
endmodule

View File

@@ -139,20 +139,6 @@ module mkProc (Proc_IFC);
FIFOF #(Bool) f_run_halt_reqs <- mkFIFOF;
FIFOF #(Bool) f_run_halt_rsps <- mkFIFOF;
// Debugger GPR read/write request/response
FIFOF #(DM_CPU_Req #(5, XLEN)) f_gpr_reqs <- mkFIFOF1;
FIFOF #(DM_CPU_Rsp #(XLEN)) f_gpr_rsps <- mkFIFOF1;
`ifdef ISA_F
// Debugger FPR read/write request/response
FIFOF #(DM_CPU_Req #(5, FLEN)) f_fpr_reqs <- mkFIFOF1;
FIFOF #(DM_CPU_Rsp #(FLEN)) f_fpr_rsps <- mkFIFOF1;
`endif
// Debugger CSR read/write request/response
FIFOF #(DM_CPU_Req #(12, XLEN)) f_csr_reqs <- mkFIFOF1;
FIFOF #(DM_CPU_Rsp #(XLEN)) f_csr_rsps <- mkFIFOF1;
`endif
// ----------------
@@ -195,14 +181,7 @@ module mkProc (Proc_IFC);
tlbToMem[i] = core[i].tlbToMem;
end
/*
// Stub out memLoader (TODO: can be Debug Module's access)
let memLoaderStub = interface MemLoaderMemClient;
interface memReq = nullFifoDeq;
interface respSt = nullFifoEnq;
endinterface;
*/
// Note: mkLLCDmaConnect is Toooba version, different from riscy-ooo version
let llc__mem_server <- mkLLCDmaConnect(llc.dma, tlbToMem);
// ================================================================
@@ -311,9 +290,7 @@ module mkProc (Proc_IFC);
// Run command when in debug mode
rule rl_debug_run ((f_run_halt_reqs.first == True)
&& (! f_gpr_reqs.notEmpty)
&& (! f_fpr_reqs.notEmpty)
&& (! f_csr_reqs.notEmpty)
// && (! f_csr_reqs.notEmpty)
&& (rg_state == CPU_DEBUG_MODE));
// if (cfg_verbosity > 1)
$display ("%0d: %m.rl_debug_run", cur_cycle);
@@ -328,9 +305,7 @@ module mkProc (Proc_IFC);
// Run command when already running
rule rl_debug_run_redundant ((f_run_halt_reqs.first == True)
&& (! f_gpr_reqs.notEmpty)
&& (! f_fpr_reqs.notEmpty)
&& (! f_csr_reqs.notEmpty)
// && (! f_csr_reqs.notEmpty)
&& fn_is_running (rg_state));
// if (cfg_verbosity > 1)
$display ("%0d: %m.rl_debug_run_redundant", cur_cycle);
@@ -380,118 +355,6 @@ module mkProc (Proc_IFC);
cur_cycle, fshow (rg_state));
endrule
// ----------------
// Debug Module CSR read/write
rule rl_debug_csr_read ((rg_state == CPU_DEBUG_MODE) && (! f_csr_reqs.first.write));
let req <- pop (f_csr_reqs);
Bit #(12) csr_addr = req.address;
let data = core [0].csr_read (csr_addr);
let rsp = DM_CPU_Rsp {ok: True, data: data};
f_csr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_read_csr: csr %0d => 0x%0h", cur_cycle, csr_addr, data);
endrule
rule rl_debug_csr_write ((rg_state == CPU_DEBUG_MODE) && f_csr_reqs.first.write);
let req <- pop (f_csr_reqs);
Bit #(12) csr_addr = req.address;
let data = req.data;
core [0].csr_write (csr_addr, data);
let rsp = DM_CPU_Rsp {ok: True, data: ?};
f_csr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_write_csr: csr 0x%0h <= 0x%0h", cur_cycle, csr_addr, data);
endrule
rule rl_debug_csr_access_busy (rg_state != CPU_DEBUG_MODE);
let req <- pop (f_csr_reqs);
let rsp = DM_CPU_Rsp {ok: False, data: ?};
f_csr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_csr_access_busy", cur_cycle);
endrule
// ----------------
// Debug Module GPR read/write
rule rl_debug_gpr_read ((rg_state == CPU_DEBUG_MODE) && (! f_gpr_reqs.first.write));
let req <- pop (f_gpr_reqs);
Bit #(5) regnum = req.address;
let data_out = core [0].gpr_read (regnum);
let rsp = DM_CPU_Rsp {ok: True, data: data_out};
f_gpr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_read_gpr: reg %0d => 0x%0h", cur_cycle, regnum, data_out);
endrule
rule rl_debug_gpr_write ((rg_state == CPU_DEBUG_MODE) && f_gpr_reqs.first.write);
let req <- pop (f_gpr_reqs);
Bit #(5) regnum = req.address;
let data_in = req.data;
core [0].gpr_write (regnum, data_in);
let rsp = DM_CPU_Rsp {ok: True, data: ?};
f_gpr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_write_gpr: reg %0d <= 0x%0h", cur_cycle, regnum, data_in);
endrule
rule rl_debug_gpr_access_busy (rg_state != CPU_DEBUG_MODE);
let req <- pop (f_gpr_reqs);
let rsp = DM_CPU_Rsp {ok: False, data: ?};
f_gpr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_gpr_access_busy", cur_cycle);
endrule
// ----------------
// Debug Module FPR read/write
`ifdef ISA_F
rule rl_debug_fpr_read ((rg_state == CPU_DEBUG_MODE) && (! f_fpr_reqs.first.write));
let req <- pop (f_fpr_reqs);
Bit #(5) regnum = req.address;
let data_out = core [0].fpr_read (regnum);
let rsp = DM_CPU_Rsp {ok: True, data: data_out};
f_fpr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_read_fpr: reg %0d => 0x%0h", cur_cycle, regnum, data_out);
endrule
rule rl_debug_fpr_write ((rg_state == CPU_DEBUG_MODE) && f_fpr_reqs.first.write);
let req <- pop (f_fpr_reqs);
Bit #(5) regnum = req.address;
let data_in = req.data;
core [0].fpr_write (regnum, data_in);
let rsp = DM_CPU_Rsp {ok: True, data: ?};
f_fpr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_write_fpr: reg %0d <= 0x%0h", cur_cycle, regnum, data_in);
endrule
rule rl_debug_fpr_access_busy (rg_state != CPU_DEBUG_MODE);
let req <- pop (f_fpr_reqs);
let rsp = DM_CPU_Rsp {ok: False, data: ?};
f_fpr_rsps.enq (rsp);
// if (cur_verbosity > 1)
$display ("%0d: %m.rl_debug_fpr_access_busy", cur_cycle);
endrule
`endif
`endif
// ================================================================
@@ -577,15 +440,15 @@ module mkProc (Proc_IFC);
endinterface
// GPR access
interface Server hart0_gpr_mem_server = toGPServer (f_gpr_reqs, f_gpr_rsps);
interface Server hart0_gpr_mem_server = core[0].hart0_gpr_mem_server;
`ifdef ISA_F
// FPR access
interface Server hart0_fpr_mem_server = toGPServer (f_fpr_reqs, f_fpr_rsps);
interface Server hart0_fpr_mem_server = core[0].hart0_fpr_mem_server;
`endif
// CSR access
interface Server hart0_csr_mem_server = toGPServer (f_csr_reqs, f_csr_rsps);
interface Server hart0_csr_mem_server = core[0].hart0_csr_mem_server;
interface debug_module_mem_server = llc__mem_server;
`endif

View File

@@ -77,6 +77,9 @@ interface RenameInput;
method Bool checkDeadlock;
// performance
method Bool doStats;
`ifdef INCLUDE_GDB_CONTROL
method Bool core_is_running;
`endif
endinterface
interface RenameStage;
@@ -302,6 +305,9 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
&& epochManager.checkEpoch[0].check(fetchStage.pipelines[0].first.main_epoch) // correct path
&& isValid(firstTrap) // take trap
&& rob.isEmpty // stall for ROB empty
`ifdef INCLUDE_GDB_CONTROL
&& inIfc.core_is_running
`endif
);
fetchStage.pipelines[0].deq;
`ifdef INCLUDE_GDB_CONTROL
@@ -416,6 +422,9 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
&& !isValid(firstTrap) // not trap
&& firstReplay // system inst needs replay
&& rob.isEmpty // stall for ROB empty
`ifdef INCLUDE_GDB_CONTROL
&& inIfc.core_is_running
`endif
);
fetchStage.pipelines[0].deq;
`ifdef INCLUDE_GDB_CONTROL
@@ -562,6 +571,9 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
// turn off speculation for mem inst only, and first inst is mem
&& (specNonMem && firstMem)
&& rob.isEmpty // stall for ROB empty to process mem inst
`ifdef INCLUDE_GDB_CONTROL
&& inIfc.core_is_running
`endif
);
fetchStage.pipelines[0].deq;
`ifdef INCLUDE_GDB_CONTROL
@@ -722,6 +734,9 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
&& (!specNone || rob.isEmpty)
// don't process mem inst if we don't allow speculation for mem inst only
&& !(specNonMem && firstMem)
`endif
`ifdef INCLUDE_GDB_CONTROL
&& inIfc.core_is_running
`endif
);
// we stop superscalar rename when an instruction cannot be processed: