Fixes for synthesis
This commit is contained in:
@@ -12,6 +12,7 @@ package DM_Abstract_Commands;
|
||||
import FIFOF :: *;
|
||||
import GetPut :: *;
|
||||
import ClientServer :: *;
|
||||
import ConfigReg :: *;
|
||||
|
||||
// ----------------
|
||||
// Other library imports
|
||||
@@ -55,7 +56,7 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
Reg #(Bool) rg_start_reg_access <- mkReg (False);
|
||||
Reg #(Bool) rg_start_reg_access <- mkConfigReg (False);
|
||||
|
||||
// FIFOs for request/response to access GPRs
|
||||
FIFOF #(DM_CPU_Req #(5, XLEN)) f_hart0_gpr_reqs <- mkFIFOF;
|
||||
@@ -86,8 +87,8 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// ----------------------------------------------------------------
|
||||
// rg_abstractcs
|
||||
|
||||
Reg #(Bool) rg_abstractcs_busy <- mkRegU;
|
||||
Reg #(DM_abstractcs_cmderr) rg_abstractcs_cmderr <- mkRegU;
|
||||
Reg #(Bool) rg_abstractcs_busy <- mkConfigRegU;
|
||||
Reg #(DM_abstractcs_cmderr) rg_abstractcs_cmderr <- mkConfigRegU;
|
||||
|
||||
// Size of program buffer, in 32b words
|
||||
Bit #(5) abstractcs_progbufsize = 0;
|
||||
@@ -95,30 +96,30 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
Bit #(4) abstractcs_datacount = ((xlen == 32) ? 1 : 2);
|
||||
|
||||
DM_Word virt_rg_abstractcs = {3'b0,
|
||||
abstractcs_progbufsize,
|
||||
11'b0,
|
||||
pack (rg_abstractcs_busy),
|
||||
1'b0,
|
||||
pack (rg_abstractcs_cmderr),
|
||||
4'b0,
|
||||
abstractcs_datacount};
|
||||
abstractcs_progbufsize,
|
||||
11'b0,
|
||||
pack (rg_abstractcs_busy),
|
||||
1'b0,
|
||||
pack (rg_abstractcs_cmderr),
|
||||
4'b0,
|
||||
abstractcs_datacount};
|
||||
|
||||
function Action fa_rg_abstractcs_write (DM_Word dm_word);
|
||||
action
|
||||
if (rg_abstractcs_busy) begin
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_BUSY;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [abstractcs] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" DM is busy with a previous abstract command");
|
||||
end
|
||||
else if (fn_abstractcs_cmderr (dm_word) != DM_ABSTRACTCS_CMDERR_NONE) begin
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_NONE;
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write [abstractcs]: clearing cmderr", cur_cycle);
|
||||
end
|
||||
else begin
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write [abstractcs]: cmderr unchanged", cur_cycle);
|
||||
end
|
||||
if (rg_abstractcs_busy) begin
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_BUSY;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [abstractcs] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" DM is busy with a previous abstract command");
|
||||
end
|
||||
else if (fn_abstractcs_cmderr (dm_word) != DM_ABSTRACTCS_CMDERR_NONE) begin
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_NONE;
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write [abstractcs]: clearing cmderr", cur_cycle);
|
||||
end
|
||||
else begin
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write [abstractcs]: cmderr unchanged", cur_cycle);
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -130,10 +131,10 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// postexec no register, since we don't support Program Buffer
|
||||
// transfer no register, since we always do transfers
|
||||
|
||||
Reg #(Bool) rg_command_access_reg_write <- mkRegU;
|
||||
Reg #(Bool) rg_command_access_reg_write <- mkConfigRegU;
|
||||
|
||||
// regno: we only implement lower 13 bits of this 16-bit field
|
||||
Reg #(Bit #(13)) rg_command_access_reg_regno <- mkRegU;
|
||||
Reg #(Bit #(13)) rg_command_access_reg_regno <- mkConfigRegU;
|
||||
|
||||
DM_Word virt_rg_command = fn_mk_command_access_reg (
|
||||
DM_COMMAND_ACCESS_REG_SIZE_LOWER32
|
||||
@@ -144,78 +145,78 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
|
||||
function Action fa_rg_command_write (DM_Word dm_word);
|
||||
action
|
||||
// TODO: check that CPU is halted, else set cmderr = DM_ABSTRACTCS_CMDERR_HALT_RESUME
|
||||
// TODO: check that CPU is halted, else set cmderr = DM_ABSTRACTCS_CMDERR_HALT_RESUME
|
||||
|
||||
DM_abstractcs_cmderr cmderr = rg_abstractcs_cmderr;
|
||||
let size = fn_command_access_reg_size (dm_word);
|
||||
DM_abstractcs_cmderr cmderr = rg_abstractcs_cmderr;
|
||||
let size = fn_command_access_reg_size (dm_word);
|
||||
|
||||
// Ignore if 'cmderr' is non-zero
|
||||
if (cmderr != DM_ABSTRACTCS_CMDERR_NONE) begin
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" Ignoring since 'cmderr' is 0x%0h", cmderr);
|
||||
end
|
||||
else begin
|
||||
if (rg_abstractcs_busy) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_BUSY;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" DM is busy with a previous abstract command");
|
||||
end
|
||||
// Ignore if 'cmderr' is non-zero
|
||||
if (cmderr != DM_ABSTRACTCS_CMDERR_NONE) begin
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" Ignoring since 'cmderr' is 0x%0h", cmderr);
|
||||
end
|
||||
else begin
|
||||
if (rg_abstractcs_busy) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_BUSY;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" DM is busy with a previous abstract command");
|
||||
end
|
||||
|
||||
// Only 'Access Reg' cmdtype is supported
|
||||
else if (fn_command_cmdtype (dm_word) != DM_COMMAND_CMDTYPE_ACCESS_REG) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" ", fshow (fn_command_cmdtype (dm_word)), " not supported");
|
||||
end
|
||||
// Only 'Access Reg' cmdtype is supported
|
||||
else if (fn_command_cmdtype (dm_word) != DM_COMMAND_CMDTYPE_ACCESS_REG) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" ", fshow (fn_command_cmdtype (dm_word)), " not supported");
|
||||
end
|
||||
|
||||
`ifdef RV32
|
||||
// Only lower 32-bit access is supported
|
||||
else if (size != DM_COMMAND_ACCESS_REG_SIZE_LOWER32) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, ",
|
||||
fshow (fn_command_access_reg_size (dm_word)), " not supported in RV32 mode");
|
||||
end
|
||||
// Only lower 32-bit access is supported
|
||||
else if (size != DM_COMMAND_ACCESS_REG_SIZE_LOWER32) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, ",
|
||||
fshow (fn_command_access_reg_size (dm_word)), " not supported in RV32 mode");
|
||||
end
|
||||
`endif
|
||||
`ifdef RV64
|
||||
// Only lower 32-bit and 64-bit access is supported
|
||||
else if (size != DM_COMMAND_ACCESS_REG_SIZE_LOWER64)
|
||||
begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, ",
|
||||
fshow (fn_command_access_reg_size (dm_word)), " not supported in RV64 mode");
|
||||
end
|
||||
// Only lower 32-bit and 64-bit access is supported
|
||||
else if (size != DM_COMMAND_ACCESS_REG_SIZE_LOWER64)
|
||||
begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, ",
|
||||
fshow (fn_command_access_reg_size (dm_word)), " not supported in RV64 mode");
|
||||
end
|
||||
`endif
|
||||
|
||||
// 'postexec' is not supported
|
||||
else if (fn_command_access_reg_postexec (dm_word) == True) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, postexec not supported");
|
||||
end
|
||||
// 'postexec' is not supported
|
||||
else if (fn_command_access_reg_postexec (dm_word) == True) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, postexec not supported");
|
||||
end
|
||||
|
||||
// non-'transfer' is not supported
|
||||
else if (fn_command_access_reg_transfer (dm_word) == False) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, no-transfer not supported");
|
||||
end
|
||||
// non-'transfer' is not supported
|
||||
else if (fn_command_access_reg_transfer (dm_word) == False) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, no-transfer not supported");
|
||||
end
|
||||
|
||||
else begin
|
||||
Bool is_write = fn_command_access_reg_write (dm_word);
|
||||
Bit #(13) regno = truncate (fn_command_access_reg_regno (dm_word));
|
||||
else begin
|
||||
Bool is_write = fn_command_access_reg_write (dm_word);
|
||||
Bit #(13) regno = truncate (fn_command_access_reg_regno (dm_word));
|
||||
|
||||
rg_command_access_reg_write <= is_write;
|
||||
rg_command_access_reg_regno <= regno;
|
||||
rg_abstractcs_busy <= True;
|
||||
rg_start_reg_access <= True;
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NONE;
|
||||
rg_command_access_reg_write <= is_write;
|
||||
rg_command_access_reg_regno <= regno;
|
||||
rg_abstractcs_busy <= True;
|
||||
rg_start_reg_access <= True;
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NONE;
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: OKAY", cur_cycle, dm_word);
|
||||
end
|
||||
rg_abstractcs_cmderr <= cmderr;
|
||||
end
|
||||
end
|
||||
rg_abstractcs_cmderr <= cmderr;
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -223,14 +224,14 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// Register reads and writes
|
||||
|
||||
Bool is_csr = ( (fromInteger (dm_command_access_reg_regno_csr_0) <= rg_command_access_reg_regno)
|
||||
&& (rg_command_access_reg_regno <= fromInteger (dm_command_access_reg_regno_csr_FFF)));
|
||||
&& (rg_command_access_reg_regno <= fromInteger (dm_command_access_reg_regno_csr_FFF)));
|
||||
|
||||
Bool is_gpr = ( (fromInteger (dm_command_access_reg_regno_gpr_0) <= rg_command_access_reg_regno)
|
||||
&& (rg_command_access_reg_regno <= fromInteger (dm_command_access_reg_regno_gpr_1F)));
|
||||
&& (rg_command_access_reg_regno <= fromInteger (dm_command_access_reg_regno_gpr_1F)));
|
||||
|
||||
`ifdef ISA_F
|
||||
Bool is_fpr = ( (fromInteger (dm_command_access_reg_regno_fpr_0) <= rg_command_access_reg_regno)
|
||||
&& (rg_command_access_reg_regno <= fromInteger (dm_command_access_reg_regno_fpr_1F)));
|
||||
&& (rg_command_access_reg_regno <= fromInteger (dm_command_access_reg_regno_fpr_1F)));
|
||||
`else
|
||||
Bool is_fpr = False;
|
||||
`endif
|
||||
@@ -243,33 +244,33 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// Write CSR
|
||||
|
||||
rule rl_csr_write_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& is_csr);
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& is_csr);
|
||||
let req = DM_CPU_Req {write: True,
|
||||
address: csr_addr,
|
||||
address: csr_addr,
|
||||
`ifdef RV32
|
||||
data: rg_data0
|
||||
data: rg_data0
|
||||
`endif
|
||||
`ifdef RV64
|
||||
data: {rg_data1, rg_data0}
|
||||
data: {rg_data1, rg_data0}
|
||||
`endif
|
||||
};
|
||||
};
|
||||
f_hart0_csr_reqs.enq (req);
|
||||
rg_start_reg_access <= False;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_write_start: ", cur_cycle, fshow (req));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_write_start: ", cur_cycle, fshow (req));
|
||||
endrule
|
||||
|
||||
// ----------------
|
||||
|
||||
rule rl_csr_write_finish (rg_abstractcs_busy
|
||||
&& rg_command_access_reg_write
|
||||
&& is_csr);
|
||||
&& rg_command_access_reg_write
|
||||
&& is_csr);
|
||||
let rsp <- pop (f_hart0_csr_rsps);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_write_finish: ", cur_cycle, fshow (rsp));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_write_finish: ", cur_cycle, fshow (rsp));
|
||||
|
||||
rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME);
|
||||
rg_abstractcs_busy <= False;
|
||||
@@ -279,26 +280,26 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// Read CSR
|
||||
|
||||
rule rl_csr_read_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_csr);
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_csr);
|
||||
Bit #(XLEN) data = ?;
|
||||
let req = DM_CPU_Req {write: False, address: csr_addr, data: data};
|
||||
f_hart0_csr_reqs.enq (req);
|
||||
rg_start_reg_access <= False;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_read_start: ", cur_cycle, fshow (req));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_read_start: ", cur_cycle, fshow (req));
|
||||
endrule
|
||||
|
||||
// ----------------
|
||||
|
||||
rule rl_csr_read_finish ( rg_abstractcs_busy
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_csr);
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_csr);
|
||||
let rsp <- pop (f_hart0_csr_rsps);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_read_finish: ", cur_cycle, fshow (rsp));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_read_finish: ", cur_cycle, fshow (rsp));
|
||||
|
||||
rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME);
|
||||
`ifdef RV32
|
||||
@@ -315,32 +316,32 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// Write GPR
|
||||
|
||||
rule rl_gpr_write_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& is_gpr);
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& is_gpr);
|
||||
let req = DM_CPU_Req {write: True,
|
||||
address: gpr_addr,
|
||||
address: gpr_addr,
|
||||
`ifdef RV32
|
||||
data: rg_data0
|
||||
data: rg_data0
|
||||
`endif
|
||||
`ifdef RV64
|
||||
data: {rg_data1, rg_data0}
|
||||
data: {rg_data1, rg_data0}
|
||||
`endif
|
||||
};
|
||||
};
|
||||
f_hart0_gpr_reqs.enq (req);
|
||||
rg_start_reg_access <= False;
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_write_start: ", cur_cycle, fshow (req));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_write_start: ", cur_cycle, fshow (req));
|
||||
endrule
|
||||
|
||||
// ----------------
|
||||
|
||||
rule rl_gpr_write_finish ( rg_abstractcs_busy
|
||||
&& rg_command_access_reg_write
|
||||
&& is_gpr);
|
||||
&& rg_command_access_reg_write
|
||||
&& is_gpr);
|
||||
let rsp <- pop (f_hart0_gpr_rsps);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_write_finish: ", cur_cycle, fshow (rsp));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_write_finish: ", cur_cycle, fshow (rsp));
|
||||
|
||||
rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME);
|
||||
rg_abstractcs_busy <= False;
|
||||
@@ -350,26 +351,26 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// Read GPR
|
||||
|
||||
rule rl_gpr_read_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_gpr);
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_gpr);
|
||||
Bit #(XLEN) data = ?;
|
||||
let req = DM_CPU_Req {write: False, address: gpr_addr, data: data };
|
||||
f_hart0_gpr_reqs.enq (req);
|
||||
rg_start_reg_access <= False;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_read_start: ", cur_cycle, fshow (req));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_read_start: ", cur_cycle, fshow (req));
|
||||
endrule
|
||||
|
||||
// ----------------
|
||||
|
||||
rule rl_gpr_read_finish ( rg_abstractcs_busy
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_gpr);
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_gpr);
|
||||
let rsp <- pop (f_hart0_gpr_rsps);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_read_finish: ", cur_cycle, fshow (rsp));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_read_finish: ", cur_cycle, fshow (rsp));
|
||||
|
||||
`ifdef RV32
|
||||
rg_data0 <= rsp.data;
|
||||
@@ -388,32 +389,32 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
`ifdef ISA_F
|
||||
|
||||
rule rl_fpr_write_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& is_fpr);
|
||||
let req = DM_CPU_Req {write: True,
|
||||
address: fpr_addr,
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& is_fpr);
|
||||
DM_CPU_Req#(5, ISA_Decls::FLEN) req = DM_CPU_Req {write: True,
|
||||
address: fpr_addr,
|
||||
`ifdef RV32
|
||||
data: rg_data0
|
||||
data: unpack(zeroExtend(rg_data0))
|
||||
`endif
|
||||
`ifdef RV64
|
||||
data: {rg_data1, rg_data0}
|
||||
data: unpack({rg_data1, rg_data0})
|
||||
`endif
|
||||
};
|
||||
};
|
||||
f_hart0_fpr_reqs.enq (req);
|
||||
rg_start_reg_access <= False;
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_write_start: ", cur_cycle, fshow (req));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_write_start: ", cur_cycle, fshow (req));
|
||||
endrule
|
||||
|
||||
// ----------------
|
||||
|
||||
rule rl_fpr_write_finish ( rg_abstractcs_busy
|
||||
&& rg_command_access_reg_write
|
||||
&& is_fpr);
|
||||
&& rg_command_access_reg_write
|
||||
&& is_fpr);
|
||||
let rsp <- pop (f_hart0_fpr_rsps);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_write_finish: ", cur_cycle, fshow (rsp));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_write_finish: ", cur_cycle, fshow (rsp));
|
||||
|
||||
rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME);
|
||||
rg_abstractcs_busy <= False;
|
||||
@@ -423,32 +424,29 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// Read FPR
|
||||
|
||||
rule rl_fpr_read_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_fpr);
|
||||
Bit #(XLEN) data = ?;
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_fpr);
|
||||
Bit #(FLEN) data = ?;
|
||||
let req = DM_CPU_Req {write: False, address: fpr_addr, data: data };
|
||||
f_hart0_fpr_reqs.enq (req);
|
||||
rg_start_reg_access <= False;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_read_start: ", cur_cycle, fshow (req));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_read_start: ", cur_cycle, fshow (req));
|
||||
endrule
|
||||
|
||||
// ----------------
|
||||
|
||||
rule rl_fpr_read_finish ( rg_abstractcs_busy
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_fpr);
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_fpr);
|
||||
let rsp <- pop (f_hart0_fpr_rsps);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_read_finish: ", cur_cycle, fshow (rsp));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_read_finish: ", cur_cycle, fshow (rsp));
|
||||
|
||||
`ifdef RV32
|
||||
rg_data0 <= rsp.data;
|
||||
`endif
|
||||
`ifdef RV64
|
||||
rg_data0 <= truncate (rsp.data);
|
||||
`ifdef RV64
|
||||
rg_data1 <= rsp.data[63:32];
|
||||
`endif
|
||||
rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME);
|
||||
@@ -461,12 +459,12 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// Read/Write unknown address
|
||||
|
||||
rule rl_unknown_write_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& (! is_csr) && (! is_gpr) && (! is_fpr));
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& (! is_csr) && (! is_gpr) && (! is_fpr));
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_unknown_write_start: unknown RISC-V regno [0x%0h] <= 0x%08h",
|
||||
cur_cycle, rg_command_access_reg_regno, rg_data0);
|
||||
$display ("%0d: DM_Abstract_Commands.rl_unknown_write_start: unknown RISC-V regno [0x%0h] <= 0x%08h",
|
||||
cur_cycle, rg_command_access_reg_regno, rg_data0);
|
||||
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_OTHER;
|
||||
rg_start_reg_access <= False;
|
||||
@@ -474,12 +472,12 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
endrule
|
||||
|
||||
rule rl_unknown_read_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& (! is_csr) && (! is_gpr) && (! is_fpr));
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& (! is_csr) && (! is_gpr) && (! is_fpr));
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_unknown_read_start: unknown RISC-V regno [0x%0h]",
|
||||
cur_cycle, rg_command_access_reg_regno);
|
||||
$display ("%0d: DM_Abstract_Commands.rl_unknown_read_start: unknown RISC-V regno [0x%0h]",
|
||||
cur_cycle, rg_command_access_reg_regno);
|
||||
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_OTHER;
|
||||
rg_start_reg_access <= False;
|
||||
@@ -509,7 +507,7 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
`endif
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands: reset", cur_cycle);
|
||||
$display ("%0d: DM_Abstract_Commands: reset", cur_cycle);
|
||||
endmethod
|
||||
|
||||
// ----------------
|
||||
@@ -517,64 +515,64 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
|
||||
method ActionValue #(DM_Word) av_read (DM_Addr dm_addr);
|
||||
actionvalue
|
||||
let dm_addr_name = fshow_dm_addr (dm_addr);
|
||||
DM_Word dm_word = case (dm_addr)
|
||||
dm_addr_abstractcs: virt_rg_abstractcs;
|
||||
dm_addr_command: virt_rg_command;
|
||||
dm_addr_data0: rg_data0;
|
||||
let dm_addr_name = fshow_dm_addr (dm_addr);
|
||||
DM_Word dm_word = case (dm_addr)
|
||||
dm_addr_abstractcs: virt_rg_abstractcs;
|
||||
dm_addr_command: virt_rg_command;
|
||||
dm_addr_data0: rg_data0;
|
||||
`ifdef RV64
|
||||
dm_addr_data1: rg_data1;
|
||||
dm_addr_data1: rg_data1;
|
||||
`endif
|
||||
// dm_addr_data2..data3
|
||||
// dm_addr_abstractauto
|
||||
// dm_addr_progbuf0..15
|
||||
endcase;
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.av_read: [", cur_cycle, dm_addr_name, "] => 0x%08h", dm_word);
|
||||
return dm_word;
|
||||
// dm_addr_data2..data3
|
||||
// dm_addr_abstractauto
|
||||
// dm_addr_progbuf0..15
|
||||
endcase;
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.av_read: [", cur_cycle, dm_addr_name, "] => 0x%08h", dm_word);
|
||||
return dm_word;
|
||||
endactionvalue
|
||||
endmethod
|
||||
|
||||
method Action write (DM_Addr dm_addr, DM_Word dm_word);
|
||||
action
|
||||
let dm_addr_name = fshow_dm_addr (dm_addr);
|
||||
let dm_addr_name = fshow_dm_addr (dm_addr);
|
||||
|
||||
if (dm_addr == dm_addr_abstractcs)
|
||||
fa_rg_abstractcs_write (dm_word);
|
||||
if (dm_addr == dm_addr_abstractcs)
|
||||
fa_rg_abstractcs_write (dm_word);
|
||||
|
||||
else if (rg_abstractcs_cmderr != DM_ABSTRACTCS_CMDERR_NONE) begin
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name, "] <= 0x%08h: ERROR", dm_word);
|
||||
$display (" Ignoring: previous cmderr ", fshow (rg_abstractcs_cmderr));
|
||||
end
|
||||
end
|
||||
else if (rg_abstractcs_cmderr != DM_ABSTRACTCS_CMDERR_NONE) begin
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name, "] <= 0x%08h: ERROR", dm_word);
|
||||
$display (" Ignoring: previous cmderr ", fshow (rg_abstractcs_cmderr));
|
||||
end
|
||||
end
|
||||
|
||||
else if (dm_addr == dm_addr_command)
|
||||
fa_rg_command_write (dm_word);
|
||||
else if (dm_addr == dm_addr_command)
|
||||
fa_rg_command_write (dm_word);
|
||||
|
||||
else if (dm_addr == dm_addr_data0) begin
|
||||
rg_data0 <= dm_word;
|
||||
else if (dm_addr == dm_addr_data0) begin
|
||||
rg_data0 <= dm_word;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name, "] <= 0x%08h", dm_word);
|
||||
end
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name, "] <= 0x%08h", dm_word);
|
||||
end
|
||||
`ifdef RV64
|
||||
else if (dm_addr == dm_addr_data1) begin
|
||||
rg_data1 <= dm_word;
|
||||
else if (dm_addr == dm_addr_data1) begin
|
||||
rg_data1 <= dm_word;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name, "] <= 0x%08h", dm_word);
|
||||
end
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name, "] <= 0x%08h", dm_word);
|
||||
end
|
||||
`endif
|
||||
else begin
|
||||
// dm_addr_data2..12
|
||||
// dm_addr_abstractauto
|
||||
// dm_addr_progbuf0..15
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
else begin
|
||||
// dm_addr_data2..12
|
||||
// dm_addr_abstractauto
|
||||
// dm_addr_progbuf0..15
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name,
|
||||
"] <= 0x%08h: ERROR: not supported", dm_word);
|
||||
end
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name,
|
||||
"] <= 0x%08h: ERROR: not supported", dm_word);
|
||||
end
|
||||
endaction
|
||||
endmethod
|
||||
|
||||
|
||||
@@ -83,49 +83,49 @@ DM_Addr dm_addr_sbdata3 = 'h3f;
|
||||
|
||||
function Fmt fshow_dm_addr (DM_Addr dm_addr);
|
||||
return case (dm_addr)
|
||||
// Run Control
|
||||
dm_addr_dmcontrol: $format ("dm_addr_dmcontrol");
|
||||
dm_addr_dmstatus: $format ("dm_addr_dmstatus");
|
||||
dm_addr_hartinfo: $format ("dm_addr_hartinfo");
|
||||
dm_addr_haltsum: $format ("dm_addr_haltsum");
|
||||
dm_addr_hawindowsel: $format ("dm_addr_hawindowsel");
|
||||
dm_addr_hawindow: $format ("dm_addr_hawindow");
|
||||
dm_addr_devtreeaddr0: $format ("dm_addr_devtreeaddr0");
|
||||
dm_addr_authdata: $format ("dm_addr_authdata");
|
||||
dm_addr_haltregion0: $format ("dm_addr_haltregion0");
|
||||
dm_addr_haltregion31: $format ("dm_addr_haltregion31");
|
||||
// Run Control
|
||||
dm_addr_dmcontrol: $format ("dm_addr_dmcontrol");
|
||||
dm_addr_dmstatus: $format ("dm_addr_dmstatus");
|
||||
dm_addr_hartinfo: $format ("dm_addr_hartinfo");
|
||||
dm_addr_haltsum: $format ("dm_addr_haltsum");
|
||||
dm_addr_hawindowsel: $format ("dm_addr_hawindowsel");
|
||||
dm_addr_hawindow: $format ("dm_addr_hawindow");
|
||||
dm_addr_devtreeaddr0: $format ("dm_addr_devtreeaddr0");
|
||||
dm_addr_authdata: $format ("dm_addr_authdata");
|
||||
dm_addr_haltregion0: $format ("dm_addr_haltregion0");
|
||||
dm_addr_haltregion31: $format ("dm_addr_haltregion31");
|
||||
dm_addr_verbosity: $format ("dm_addr_verbosity");
|
||||
|
||||
// Abstract Commands
|
||||
dm_addr_abstractcs: $format ("dm_addr_abstractcs");
|
||||
dm_addr_command: $format ("dm_addr_command");
|
||||
dm_addr_data0: $format ("dm_addr_data0");
|
||||
dm_addr_data1: $format ("dm_addr_data1");
|
||||
dm_addr_data2: $format ("dm_addr_data2");
|
||||
dm_addr_data3: $format ("dm_addr_data3");
|
||||
dm_addr_data4: $format ("dm_addr_data4");
|
||||
dm_addr_data5: $format ("dm_addr_data5");
|
||||
dm_addr_data6: $format ("dm_addr_data6");
|
||||
dm_addr_data7: $format ("dm_addr_data7");
|
||||
dm_addr_data8: $format ("dm_addr_data8");
|
||||
dm_addr_data9: $format ("dm_addr_data9");
|
||||
dm_addr_data10: $format ("dm_addr_data10");
|
||||
dm_addr_data11: $format ("dm_addr_data11");
|
||||
dm_addr_abstractauto: $format ("dm_addr_abstractauto");
|
||||
dm_addr_progbuf0: $format ("dm_addr_progbuf0");
|
||||
// Abstract Commands
|
||||
dm_addr_abstractcs: $format ("dm_addr_abstractcs");
|
||||
dm_addr_command: $format ("dm_addr_command");
|
||||
dm_addr_data0: $format ("dm_addr_data0");
|
||||
dm_addr_data1: $format ("dm_addr_data1");
|
||||
dm_addr_data2: $format ("dm_addr_data2");
|
||||
dm_addr_data3: $format ("dm_addr_data3");
|
||||
dm_addr_data4: $format ("dm_addr_data4");
|
||||
dm_addr_data5: $format ("dm_addr_data5");
|
||||
dm_addr_data6: $format ("dm_addr_data6");
|
||||
dm_addr_data7: $format ("dm_addr_data7");
|
||||
dm_addr_data8: $format ("dm_addr_data8");
|
||||
dm_addr_data9: $format ("dm_addr_data9");
|
||||
dm_addr_data10: $format ("dm_addr_data10");
|
||||
dm_addr_data11: $format ("dm_addr_data11");
|
||||
dm_addr_abstractauto: $format ("dm_addr_abstractauto");
|
||||
dm_addr_progbuf0: $format ("dm_addr_progbuf0");
|
||||
|
||||
// System Bus
|
||||
dm_addr_sbcs: $format ("dm_addr_sbcs");
|
||||
dm_addr_sbaddress0: $format ("dm_addr_sbaddress0");
|
||||
dm_addr_sbaddress1: $format ("dm_addr_sbaddress1");
|
||||
dm_addr_sbaddress2: $format ("dm_addr_sbaddress2");
|
||||
dm_addr_sbdata0: $format ("dm_addr_sbdata0");
|
||||
dm_addr_sbdata1: $format ("dm_addr_sbdata1");
|
||||
dm_addr_sbdata2: $format ("dm_addr_sbdata2");
|
||||
dm_addr_sbdata3: $format ("dm_addr_sbdata3");
|
||||
// System Bus
|
||||
dm_addr_sbcs: $format ("dm_addr_sbcs");
|
||||
dm_addr_sbaddress0: $format ("dm_addr_sbaddress0");
|
||||
dm_addr_sbaddress1: $format ("dm_addr_sbaddress1");
|
||||
dm_addr_sbaddress2: $format ("dm_addr_sbaddress2");
|
||||
dm_addr_sbdata0: $format ("dm_addr_sbdata0");
|
||||
dm_addr_sbdata1: $format ("dm_addr_sbdata1");
|
||||
dm_addr_sbdata2: $format ("dm_addr_sbdata2");
|
||||
dm_addr_sbdata3: $format ("dm_addr_sbdata3");
|
||||
|
||||
default: $format ("<Unknown dm_abstract_command dm_addr 0x%0h>", dm_addr);
|
||||
endcase;
|
||||
default: $format ("<Unknown dm_abstract_command dm_addr 0x%0h>", dm_addr);
|
||||
endcase;
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -135,21 +135,21 @@ endfunction
|
||||
// 'dmcontrol' register
|
||||
|
||||
function DM_Word fn_mk_dmcontrol (Bool haltreq,
|
||||
Bool resumereq,
|
||||
Bool hartreset,
|
||||
Bool hasel,
|
||||
Bit #(10) hartsel,
|
||||
Bool ndmreset,
|
||||
Bool dmactive);
|
||||
Bool resumereq,
|
||||
Bool hartreset,
|
||||
Bool hasel,
|
||||
Bit #(10) hartsel,
|
||||
Bool ndmreset,
|
||||
Bool dmactive);
|
||||
return {pack (haltreq),
|
||||
pack (resumereq),
|
||||
pack (hartreset),
|
||||
2'b0,
|
||||
pack (hasel),
|
||||
hartsel,
|
||||
14'b0,
|
||||
pack (ndmreset),
|
||||
pack (dmactive)};
|
||||
pack (resumereq),
|
||||
pack (hartreset),
|
||||
2'b0,
|
||||
pack (hasel),
|
||||
hartsel,
|
||||
14'b0,
|
||||
pack (ndmreset),
|
||||
pack (dmactive)};
|
||||
endfunction
|
||||
|
||||
function Bool fn_dmcontrol_haltreq (DM_Word dm_word);
|
||||
@@ -241,23 +241,23 @@ endfunction
|
||||
|
||||
function Fmt fshow_dmstatus (DM_Word x);
|
||||
Fmt fmt_version = ( (x[3:0] == 0)
|
||||
? $format ("v.none")
|
||||
: ( (x[3:0] == 1)
|
||||
? $format ("v0.11")
|
||||
: ( (x[3:0] == 2)
|
||||
? $format ("v0.13")
|
||||
: $format ("v??"))));
|
||||
? $format ("v.none")
|
||||
: ( (x[3:0] == 1)
|
||||
? $format ("v0.11")
|
||||
: ( (x[3:0] == 2)
|
||||
? $format ("v0.13")
|
||||
: $format ("v??"))));
|
||||
|
||||
return ( $format ("(all/any) ")
|
||||
+ $format ("resumeack %0d/%0d ", x[17], x[16])
|
||||
+ $format ("nonexistent %0d/%0d ", x[15], x[14])
|
||||
+ $format ("unavail %0d/%0d ", x[13], x[12])
|
||||
+ $format ("running %0d/%0d ", x[11], x[10])
|
||||
+ $format ("halted %0d/%0d ", x[9], x[8])
|
||||
+ $format ("authenticated %0d ", x[7])
|
||||
+ $format ("authbusy %0d ", x[6])
|
||||
+ $format ("devtreevalid %0d ", x[4])
|
||||
+ fmt_version);
|
||||
+ $format ("resumeack %0d/%0d ", x[17], x[16])
|
||||
+ $format ("nonexistent %0d/%0d ", x[15], x[14])
|
||||
+ $format ("unavail %0d/%0d ", x[13], x[12])
|
||||
+ $format ("running %0d/%0d ", x[11], x[10])
|
||||
+ $format ("halted %0d/%0d ", x[9], x[8])
|
||||
+ $format ("authenticated %0d ", x[7])
|
||||
+ $format ("authbusy %0d ", x[6])
|
||||
+ $format ("devtreevalid %0d ", x[4])
|
||||
+ fmt_version);
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -267,13 +267,13 @@ endfunction
|
||||
// 'dm_abstractcs' register
|
||||
|
||||
typedef enum {DM_ABSTRACTCS_CMDERR_NONE, // 0
|
||||
DM_ABSTRACTCS_CMDERR_BUSY, // 1
|
||||
DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED, // 2
|
||||
DM_ABSTRACTCS_CMDERR_EXCEPTION, // 3
|
||||
DM_ABSTRACTCS_CMDERR_HALT_RESUME, // 4
|
||||
DM_ABSTRACTCS_CMDERR_UNDEF5, // 5
|
||||
DM_ABSTRACTCS_CMDERR_UNDEF6, // 6
|
||||
DM_ABSTRACTCS_CMDERR_OTHER // 7
|
||||
DM_ABSTRACTCS_CMDERR_BUSY, // 1
|
||||
DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED, // 2
|
||||
DM_ABSTRACTCS_CMDERR_EXCEPTION, // 3
|
||||
DM_ABSTRACTCS_CMDERR_HALT_RESUME, // 4
|
||||
DM_ABSTRACTCS_CMDERR_UNDEF5, // 5
|
||||
DM_ABSTRACTCS_CMDERR_UNDEF6, // 6
|
||||
DM_ABSTRACTCS_CMDERR_OTHER // 7
|
||||
} DM_abstractcs_cmderr
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
@@ -304,18 +304,18 @@ endfunction
|
||||
// 'command' register
|
||||
|
||||
typedef enum {DM_COMMAND_CMDTYPE_ACCESS_REG,
|
||||
DM_COMMAND_CMDTYPE_QUICK_ACCESS
|
||||
DM_COMMAND_CMDTYPE_QUICK_ACCESS
|
||||
} DM_command_cmdtype
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
typedef enum {DM_COMMAND_ACCESS_REG_SIZE_UNDEF0, // 0
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF1, // 1
|
||||
DM_COMMAND_ACCESS_REG_SIZE_LOWER32, // 2
|
||||
DM_COMMAND_ACCESS_REG_SIZE_LOWER64, // 3
|
||||
DM_COMMAND_ACCESS_REG_SIZE_LOWER128, // 4
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF5, // 5
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF6, // 6
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF7 // 7
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF1, // 1
|
||||
DM_COMMAND_ACCESS_REG_SIZE_LOWER32, // 2
|
||||
DM_COMMAND_ACCESS_REG_SIZE_LOWER64, // 3
|
||||
DM_COMMAND_ACCESS_REG_SIZE_LOWER128, // 4
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF5, // 5
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF6, // 6
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF7 // 7
|
||||
} DM_command_access_reg_size
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
@@ -327,20 +327,20 @@ Integer dm_command_access_reg_regno_fpr_0 = 'h1020;
|
||||
Integer dm_command_access_reg_regno_fpr_1F = 'h103F;
|
||||
|
||||
function DM_Word fn_mk_command_access_reg (DM_command_access_reg_size size,
|
||||
Bool postexec,
|
||||
Bool transfer,
|
||||
Bool write,
|
||||
Bit #(16) regno);
|
||||
Bool postexec,
|
||||
Bool transfer,
|
||||
Bool write,
|
||||
Bit #(16) regno);
|
||||
Bit #(8) b8_cmdtype = zeroExtend (pack (DM_COMMAND_CMDTYPE_ACCESS_REG));
|
||||
Bit #(3) b3_size = pack (size);
|
||||
return {b8_cmdtype,
|
||||
1'b0,
|
||||
b3_size,
|
||||
1'b0,
|
||||
pack (postexec),
|
||||
pack (transfer),
|
||||
pack (write),
|
||||
regno};
|
||||
1'b0,
|
||||
b3_size,
|
||||
1'b0,
|
||||
pack (postexec),
|
||||
pack (transfer),
|
||||
pack (write),
|
||||
regno};
|
||||
endfunction
|
||||
|
||||
function DM_command_cmdtype fn_command_cmdtype (DM_Word dm_word);
|
||||
@@ -374,10 +374,10 @@ endfunction
|
||||
// 'dm_sbcs' register
|
||||
|
||||
typedef enum {DM_SBACCESS_8_BIT,
|
||||
DM_SBACCESS_16_BIT,
|
||||
DM_SBACCESS_32_BIT,
|
||||
DM_SBACCESS_64_BIT,
|
||||
DM_SBACCESS_128_BIT
|
||||
DM_SBACCESS_16_BIT,
|
||||
DM_SBACCESS_32_BIT,
|
||||
DM_SBACCESS_64_BIT,
|
||||
DM_SBACCESS_128_BIT
|
||||
} DM_sbaccess
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
@@ -392,47 +392,47 @@ function Integer fn_sbaccess_to_addr_incr (DM_sbaccess sbaccess);
|
||||
endfunction
|
||||
|
||||
typedef enum {DM_SBERROR_NONE, // 0
|
||||
DM_SBERROR_TIMEOUT, // 1
|
||||
DM_SBERROR_BADADDR, // 2
|
||||
DM_SBERROR_OTHER, // 3
|
||||
DM_SBERROR_BUSY_STALE, // 4
|
||||
DM_SBERROR_UNDEF5, // 5
|
||||
DM_SBERROR_UNDEF6, // 6
|
||||
DM_SBERROR_UNDEF7_W1C // 7, used in writes, to clear sberror
|
||||
DM_SBERROR_TIMEOUT, // 1
|
||||
DM_SBERROR_BADADDR, // 2
|
||||
DM_SBERROR_OTHER, // 3
|
||||
DM_SBERROR_BUSY_STALE, // 4
|
||||
DM_SBERROR_UNDEF5, // 5
|
||||
DM_SBERROR_UNDEF6, // 6
|
||||
DM_SBERROR_UNDEF7_W1C // 7, used in writes, to clear sberror
|
||||
} DM_sberror
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
// Constructor
|
||||
|
||||
function DM_Word fn_mk_sbcs_val (Bit #(3) sbversion,
|
||||
Bool sbbusyerror,
|
||||
Bool sbbusy,
|
||||
Bool sbreadonaddr,
|
||||
DM_sbaccess sbaccess,
|
||||
Bool sbautoincrement,
|
||||
Bool sbreadondata,
|
||||
DM_sberror sberror,
|
||||
Bit #(7) sbasize,
|
||||
Bit #(1) sbaccess128,
|
||||
Bit #(1) sbaccess64,
|
||||
Bit #(1) sbaccess32,
|
||||
Bit #(1) sbaccess16,
|
||||
Bit #(1) sbaccess8);
|
||||
Bool sbbusyerror,
|
||||
Bool sbbusy,
|
||||
Bool sbreadonaddr,
|
||||
DM_sbaccess sbaccess,
|
||||
Bool sbautoincrement,
|
||||
Bool sbreadondata,
|
||||
DM_sberror sberror,
|
||||
Bit #(7) sbasize,
|
||||
Bit #(1) sbaccess128,
|
||||
Bit #(1) sbaccess64,
|
||||
Bit #(1) sbaccess32,
|
||||
Bit #(1) sbaccess16,
|
||||
Bit #(1) sbaccess8);
|
||||
return {sbversion,
|
||||
6'b0,
|
||||
pack (sbbusyerror),
|
||||
pack (sbbusy),
|
||||
pack (sbreadonaddr),
|
||||
pack (sbaccess),
|
||||
pack (sbautoincrement),
|
||||
pack (sbreadondata),
|
||||
pack (sberror),
|
||||
sbasize,
|
||||
sbaccess128,
|
||||
sbaccess64,
|
||||
sbaccess32,
|
||||
sbaccess16,
|
||||
sbaccess8};
|
||||
6'b0,
|
||||
pack (sbbusyerror),
|
||||
pack (sbbusy),
|
||||
pack (sbreadonaddr),
|
||||
pack (sbaccess),
|
||||
pack (sbautoincrement),
|
||||
pack (sbreadondata),
|
||||
pack (sberror),
|
||||
sbasize,
|
||||
sbaccess128,
|
||||
sbaccess64,
|
||||
sbaccess32,
|
||||
sbaccess16,
|
||||
sbaccess8};
|
||||
endfunction
|
||||
|
||||
// Selectors
|
||||
@@ -456,35 +456,35 @@ function Bool fn_sbcs_sbaccess8 (DM_Word dm_word); return unpack (
|
||||
|
||||
function Fmt fshow_sbcs (DM_Word dm_word);
|
||||
return ( $format ("SBCS{")
|
||||
+ $format ("sbversion %0d", fn_sbcs_sbversion (dm_word))
|
||||
+ $format (" sbbusyerror %0d", fn_sbcs_sbbusyerror (dm_word))
|
||||
+ $format (" sbbusy %0d", fn_sbcs_sbbusy (dm_word))
|
||||
+ $format (" sbreadonaddr ") + fshow (fn_sbcs_sbreadonaddr (dm_word))
|
||||
+ $format (" sbaccess ") + fshow (fn_sbcs_sbaccess (dm_word))
|
||||
+ $format (" sbautoincrement ") + fshow (fn_sbcs_sbautoincrement (dm_word))
|
||||
+ $format (" sbreadondata ") + fshow (fn_sbcs_sbreadondata (dm_word))
|
||||
+ $format (" sberror ") + fshow (fn_sbcs_sberror (dm_word))
|
||||
+ $format (" sbasize %0d", fn_sbcs_sbasize (dm_word))
|
||||
+ $format (" sbaccess")
|
||||
+ ((fn_sbcs_sbaccess128 (dm_word)) ? $format ("_128") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess64 (dm_word)) ? $format ("_64") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess32 (dm_word)) ? $format ("_32") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess16 (dm_word)) ? $format ("_16") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess8 (dm_word)) ? $format ("_8") : $format ("x"))
|
||||
+ $format ("}"));
|
||||
+ $format ("sbversion %0d", fn_sbcs_sbversion (dm_word))
|
||||
+ $format (" sbbusyerror %0d", fn_sbcs_sbbusyerror (dm_word))
|
||||
+ $format (" sbbusy %0d", fn_sbcs_sbbusy (dm_word))
|
||||
+ $format (" sbreadonaddr ") + fshow (fn_sbcs_sbreadonaddr (dm_word))
|
||||
+ $format (" sbaccess ") + fshow (fn_sbcs_sbaccess (dm_word))
|
||||
+ $format (" sbautoincrement ") + fshow (fn_sbcs_sbautoincrement (dm_word))
|
||||
+ $format (" sbreadondata ") + fshow (fn_sbcs_sbreadondata (dm_word))
|
||||
+ $format (" sberror ") + fshow (fn_sbcs_sberror (dm_word))
|
||||
+ $format (" sbasize %0d", fn_sbcs_sbasize (dm_word))
|
||||
+ $format (" sbaccess")
|
||||
+ ((fn_sbcs_sbaccess128 (dm_word)) ? $format ("_128") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess64 (dm_word)) ? $format ("_64") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess32 (dm_word)) ? $format ("_32") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess16 (dm_word)) ? $format ("_16") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess8 (dm_word)) ? $format ("_8") : $format ("x"))
|
||||
+ $format ("}"));
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
// DCSR 'cause' field values
|
||||
|
||||
typedef enum {DCSR_CAUSE_RESERVED0,
|
||||
DCSR_CAUSE_EBREAK,
|
||||
DCSR_CAUSE_TRIGGER,
|
||||
DCSR_CAUSE_HALTREQ,
|
||||
DCSR_CAUSE_STEP,
|
||||
DCSR_CAUSE_RESERVED5,
|
||||
DCSR_CAUSE_RESERVED6,
|
||||
DCSR_CAUSE_RESERVED7
|
||||
DCSR_CAUSE_EBREAK,
|
||||
DCSR_CAUSE_TRIGGER,
|
||||
DCSR_CAUSE_HALTREQ,
|
||||
DCSR_CAUSE_STEP,
|
||||
DCSR_CAUSE_RESERVED5,
|
||||
DCSR_CAUSE_RESERVED6,
|
||||
DCSR_CAUSE_RESERVED7
|
||||
} DCSR_Cause
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
@@ -500,12 +500,12 @@ endinterface
|
||||
// A dummy interface to tie off DMI if it is not used.
|
||||
|
||||
DMI dummy_DMI_ifc = interface DMI;
|
||||
method Action read_addr (DM_Addr dm_addr) = noAction;
|
||||
method ActionValue #(DM_Word) read_data = actionvalue
|
||||
return 0;
|
||||
endactionvalue;
|
||||
method Action write (DM_Addr dm_addr, DM_Word dm_word) = noAction;
|
||||
endinterface;
|
||||
method Action read_addr (DM_Addr dm_addr) = noAction;
|
||||
method ActionValue #(DM_Word) read_data = actionvalue
|
||||
return 0;
|
||||
endactionvalue;
|
||||
method Action write (DM_Addr dm_addr, DM_Word dm_word) = noAction;
|
||||
endinterface;
|
||||
|
||||
// ================================================================
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ package DM_Run_Control;
|
||||
import FIFOF :: *;
|
||||
import GetPut :: *;
|
||||
import ClientServer :: *;
|
||||
import ConfigReg :: *;
|
||||
|
||||
// ----------------
|
||||
// Other library imports
|
||||
@@ -115,25 +116,25 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
|
||||
Bool dmstatus_anyhalted = dmstatus_allhalted;
|
||||
|
||||
DM_Word virt_rg_dmstatus = {9'b0,
|
||||
pack (dmstatus_impebreak),
|
||||
2'b0,
|
||||
pack (dmstatus_allhavereset),
|
||||
pack (dmstatus_anyhavereset),
|
||||
pack (dmstatus_allresumeack),
|
||||
pack (dmstatus_anyresumeack),
|
||||
pack (dmstatus_allnonexistent),
|
||||
pack (dmstatus_anynonexistent),
|
||||
pack (dmstatus_allunavail),
|
||||
pack (dmstatus_anyunavail),
|
||||
pack (dmstatus_allrunning),
|
||||
pack (dmstatus_anyrunning),
|
||||
pack (dmstatus_allhalted),
|
||||
pack (dmstatus_anyhalted),
|
||||
pack (True), // authenticated
|
||||
pack (False), // authbusy
|
||||
1'b0,
|
||||
pack (False), // devtreevalid
|
||||
4'h2}; // version
|
||||
pack (dmstatus_impebreak),
|
||||
2'b0,
|
||||
pack (dmstatus_allhavereset),
|
||||
pack (dmstatus_anyhavereset),
|
||||
pack (dmstatus_allresumeack),
|
||||
pack (dmstatus_anyresumeack),
|
||||
pack (dmstatus_allnonexistent),
|
||||
pack (dmstatus_anynonexistent),
|
||||
pack (dmstatus_allunavail),
|
||||
pack (dmstatus_anyunavail),
|
||||
pack (dmstatus_allrunning),
|
||||
pack (dmstatus_anyrunning),
|
||||
pack (dmstatus_allhalted),
|
||||
pack (dmstatus_anyhalted),
|
||||
pack (True), // authenticated
|
||||
pack (False), // authbusy
|
||||
1'b0,
|
||||
pack (False), // devtreevalid
|
||||
4'h2}; // version
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// rg_dmcontrol
|
||||
@@ -142,134 +143,134 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
|
||||
// resumereq is a W1 field, no need for a register
|
||||
Reg #(Bool) rg_dmcontrol_hartreset <- mkRegU;
|
||||
Reg #(Bool) rg_dmcontrol_ndmreset <- mkRegU;
|
||||
Reg #(Bool) rg_dmcontrol_dmactive <- mkReg (False);
|
||||
Reg #(Bool) rg_dmcontrol_dmactive <- mkConfigReg (False);
|
||||
|
||||
DM_Word virt_rg_dmcontrol = {2'b0, // haltreq, resumereq (w-o)
|
||||
pack (rg_dmcontrol_hartreset),
|
||||
2'b0,
|
||||
pack (False), // hasel
|
||||
10'b0, // hartsel
|
||||
14'b0,
|
||||
pack (rg_dmcontrol_ndmreset),
|
||||
pack (rg_dmcontrol_dmactive)};
|
||||
pack (rg_dmcontrol_hartreset),
|
||||
2'b0,
|
||||
pack (False), // hasel
|
||||
10'b0, // hartsel
|
||||
14'b0,
|
||||
pack (rg_dmcontrol_ndmreset),
|
||||
pack (rg_dmcontrol_dmactive)};
|
||||
|
||||
function Action fa_rg_dmcontrol_write (DM_Word dm_word);
|
||||
action
|
||||
let haltreq = fn_dmcontrol_haltreq (dm_word);
|
||||
let resumereq = fn_dmcontrol_resumereq (dm_word);
|
||||
let hartreset = fn_dmcontrol_hartreset (dm_word);
|
||||
let hasel = fn_dmcontrol_hasel (dm_word);
|
||||
let hartsel = fn_dmcontrol_hartsel (dm_word);
|
||||
let ndmreset = fn_dmcontrol_ndmreset (dm_word);
|
||||
let dmactive = fn_dmcontrol_dmactive (dm_word);
|
||||
let haltreq = fn_dmcontrol_haltreq (dm_word);
|
||||
let resumereq = fn_dmcontrol_resumereq (dm_word);
|
||||
let hartreset = fn_dmcontrol_hartreset (dm_word);
|
||||
let hasel = fn_dmcontrol_hasel (dm_word);
|
||||
let hartsel = fn_dmcontrol_hartsel (dm_word);
|
||||
let ndmreset = fn_dmcontrol_ndmreset (dm_word);
|
||||
let dmactive = fn_dmcontrol_dmactive (dm_word);
|
||||
|
||||
rg_dmcontrol_haltreq <= haltreq;
|
||||
rg_dmcontrol_hartreset <= hartreset;
|
||||
rg_dmcontrol_ndmreset <= ndmreset;
|
||||
rg_dmcontrol_dmactive <= dmactive;
|
||||
rg_dmcontrol_haltreq <= haltreq;
|
||||
rg_dmcontrol_hartreset <= hartreset;
|
||||
rg_dmcontrol_ndmreset <= ndmreset;
|
||||
rg_dmcontrol_dmactive <= dmactive;
|
||||
|
||||
// Debug Module reset
|
||||
if (! dmactive) begin
|
||||
// Reset the DM module itself
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h (dmactive=0): resetting Debug Module",
|
||||
cur_cycle, dm_word);
|
||||
// Debug Module reset
|
||||
if (! dmactive) begin
|
||||
// Reset the DM module itself
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h (dmactive=0): resetting Debug Module",
|
||||
cur_cycle, dm_word);
|
||||
|
||||
// Error-checking
|
||||
if (ndmreset) begin
|
||||
$display (" WARNING: DM_Run_Control: dmcontrol_write 0x%08h:", dm_word);
|
||||
$display (" [1] (ndmreset) and [0] (dmactive) both asserted");
|
||||
$display (" dmactive has priority; ignoring ndmreset");
|
||||
end
|
||||
if (hartreset) begin
|
||||
$display (" WARNING: DM_Run_Control: dmcontrol_write 0x%08h:", dm_word);
|
||||
$display (" [29] (hartreset) and [0] (dmactive) both asserted");
|
||||
$display (" dmactive has priority; ignoring hartreset");
|
||||
end
|
||||
// Error-checking
|
||||
if (ndmreset) begin
|
||||
$display (" WARNING: DM_Run_Control: dmcontrol_write 0x%08h:", dm_word);
|
||||
$display (" [1] (ndmreset) and [0] (dmactive) both asserted");
|
||||
$display (" dmactive has priority; ignoring ndmreset");
|
||||
end
|
||||
if (hartreset) begin
|
||||
$display (" WARNING: DM_Run_Control: dmcontrol_write 0x%08h:", dm_word);
|
||||
$display (" [29] (hartreset) and [0] (dmactive) both asserted");
|
||||
$display (" dmactive has priority; ignoring hartreset");
|
||||
end
|
||||
|
||||
// No action here; other rules will fire (see method dmactive, Debug_Module.rl_reset)
|
||||
noAction;
|
||||
end
|
||||
// No action here; other rules will fire (see method dmactive, Debug_Module.rl_reset)
|
||||
noAction;
|
||||
end
|
||||
|
||||
// Ignore if NDM reset is in progress
|
||||
else if (rg_dmstatus_allunavail) begin
|
||||
$display ("%0d: %m.dmcontrol_write 0x%0h: ndm reset in progress; ignoring this write",
|
||||
cur_cycle, dm_word);
|
||||
end
|
||||
// Ignore if NDM reset is in progress
|
||||
else if (rg_dmstatus_allunavail) begin
|
||||
$display ("%0d: %m.dmcontrol_write 0x%0h: ndm reset in progress; ignoring this write",
|
||||
cur_cycle, dm_word);
|
||||
end
|
||||
|
||||
// Non-Debug-Module reset (platform reset) posedge: ignore
|
||||
else if ((! rg_dmcontrol_ndmreset) && ndmreset) begin
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: ndmreset: 0->1: ignoring",
|
||||
cur_cycle, dm_word);
|
||||
end
|
||||
// Non-Debug-Module reset (platform reset) posedge: ignore
|
||||
else if ((! rg_dmcontrol_ndmreset) && ndmreset) begin
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: ndmreset: 0->1: ignoring",
|
||||
cur_cycle, dm_word);
|
||||
end
|
||||
|
||||
// Non-Debug-Module reset (platform reset) negedge: do it
|
||||
else if (rg_dmcontrol_ndmreset && (! ndmreset)) begin
|
||||
Bool running = (! haltreq);
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: ndmreset: 1->0: resetting platform",
|
||||
cur_cycle, dm_word);
|
||||
$display (" Requested 'running' state = ", fshow (running));
|
||||
end
|
||||
// Non-Debug-Module reset (platform reset) negedge: do it
|
||||
else if (rg_dmcontrol_ndmreset && (! ndmreset)) begin
|
||||
Bool running = (! haltreq);
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: ndmreset: 1->0: resetting platform",
|
||||
cur_cycle, dm_word);
|
||||
$display (" Requested 'running' state = ", fshow (running));
|
||||
end
|
||||
|
||||
f_ndm_reset_reqs.enq (running);
|
||||
rg_dmstatus_allunavail <= True;
|
||||
f_ndm_reset_reqs.enq (running);
|
||||
rg_dmstatus_allunavail <= True;
|
||||
|
||||
// Error-checking
|
||||
if (hartreset) begin
|
||||
$display (" WARNING: %m.dmcontrol_write 0x%08h:", dm_word);
|
||||
$display (" Both ndmreset [1] and hartreset [29] are asserted");
|
||||
$display (" ndmreset has priority; ignoring hartreset");
|
||||
end
|
||||
// Error-checking
|
||||
if (hartreset) begin
|
||||
$display (" WARNING: %m.dmcontrol_write 0x%08h:", dm_word);
|
||||
$display (" Both ndmreset [1] and hartreset [29] are asserted");
|
||||
$display (" ndmreset has priority; ignoring hartreset");
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
// Hart reset
|
||||
else if (hartreset) begin
|
||||
Bool running = (! haltreq);
|
||||
f_hart0_reset_reqs.enq (running);
|
||||
rg_hart0_hasreset <= True;
|
||||
// Hart reset
|
||||
else if (hartreset) begin
|
||||
Bool running = (! haltreq);
|
||||
f_hart0_reset_reqs.enq (running);
|
||||
rg_hart0_hasreset <= True;
|
||||
|
||||
// Deassert platform reset
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: hartreset=1: resetting hart",
|
||||
cur_cycle, dm_word);
|
||||
$display (" Requested 'running' state = ", fshow (running));
|
||||
end
|
||||
end
|
||||
// Deassert platform reset
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: hartreset=1: resetting hart",
|
||||
cur_cycle, dm_word);
|
||||
$display (" Requested 'running' state = ", fshow (running));
|
||||
end
|
||||
end
|
||||
|
||||
// run/halt commands
|
||||
else begin
|
||||
// Deassert hart reset
|
||||
if ((verbosity != 0) && rg_dmcontrol_hartreset)
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: clearing hartreset",
|
||||
cur_cycle, dm_word);
|
||||
// run/halt commands
|
||||
else begin
|
||||
// Deassert hart reset
|
||||
if ((verbosity != 0) && rg_dmcontrol_hartreset)
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: clearing hartreset",
|
||||
cur_cycle, dm_word);
|
||||
|
||||
if (hasel)
|
||||
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: hasel is not supported",
|
||||
cur_cycle, dm_word);
|
||||
if (hasel)
|
||||
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: hasel is not supported",
|
||||
cur_cycle, dm_word);
|
||||
|
||||
if (hartsel != 0)
|
||||
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: hartsel 0x%0h not supported",
|
||||
cur_cycle, dm_word, hartsel);
|
||||
if (hartsel != 0)
|
||||
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: hartsel 0x%0h not supported",
|
||||
cur_cycle, dm_word, hartsel);
|
||||
|
||||
if (haltreq && resumereq) begin
|
||||
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: haltreq=1 and resumereq=1",
|
||||
cur_cycle, dm_word);
|
||||
$display (" This behavior is 'undefined' in the spec; ignoring");
|
||||
end
|
||||
// Resume hart(s) if not running
|
||||
else if (resumereq && (! rg_hart0_running)) begin
|
||||
f_hart0_run_halt_reqs.enq (True);
|
||||
rg_dmstatus_allresumeack <= False;
|
||||
$display ("%0d: %m.dmcontrol_write: hart0 resume request", cur_cycle);
|
||||
end
|
||||
// Halt hart(s)
|
||||
else if (haltreq && rg_hart0_running) begin
|
||||
f_hart0_run_halt_reqs.enq (False);
|
||||
$display ("%0d: %m.dmcontrol_write: hart0 halt request", cur_cycle);
|
||||
end
|
||||
end
|
||||
if (haltreq && resumereq) begin
|
||||
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: haltreq=1 and resumereq=1",
|
||||
cur_cycle, dm_word);
|
||||
$display (" This behavior is 'undefined' in the spec; ignoring");
|
||||
end
|
||||
// Resume hart(s) if not running
|
||||
else if (resumereq && (! rg_hart0_running)) begin
|
||||
f_hart0_run_halt_reqs.enq (True);
|
||||
rg_dmstatus_allresumeack <= False;
|
||||
$display ("%0d: %m.dmcontrol_write: hart0 resume request", cur_cycle);
|
||||
end
|
||||
// Halt hart(s)
|
||||
else if (haltreq && rg_hart0_running) begin
|
||||
f_hart0_run_halt_reqs.enq (False);
|
||||
$display ("%0d: %m.dmcontrol_write: hart0 halt request", cur_cycle);
|
||||
end
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -298,7 +299,7 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
|
||||
rg_hart0_running <= running;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.rl_hart0_reset_rsp: hart running = ", cur_cycle, fshow (running));
|
||||
$display ("%0d: %m.rl_hart0_reset_rdp: hart running = ", cur_cycle, fshow (running));
|
||||
endrule
|
||||
|
||||
// Response from system for NDM reset
|
||||
@@ -307,8 +308,8 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
|
||||
rg_hart0_running <= running;
|
||||
rg_dmstatus_allunavail <= False;
|
||||
|
||||
// if (verbosity != 0) TODO: UNCOMMENT AFTER DEBUGGING
|
||||
$display ("%0d: %m.rl_ndm_reset_rsp: hart running = ", cur_cycle, fshow (running));
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.rl_ndm_reset_rsp: hart running = ", cur_cycle, fshow (running));
|
||||
endrule
|
||||
|
||||
// Response from system for run/halt request
|
||||
@@ -316,10 +317,10 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
|
||||
let running <- pop (f_hart0_run_halt_rsps);
|
||||
rg_hart0_running <= running;
|
||||
if (running)
|
||||
rg_dmstatus_allresumeack <= True;
|
||||
rg_dmstatus_allresumeack <= True;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.rl_hart0_run_rsp: 'running' = ", cur_cycle, fshow (running));
|
||||
$display ("%0d: %m.rl_hart0_run_rsp: 'running' = ", cur_cycle, fshow (running));
|
||||
endrule
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
@@ -352,7 +353,7 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
|
||||
rg_verbosity <= 0;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.reset", cur_cycle);
|
||||
$display ("%0d: %m.reset", cur_cycle);
|
||||
endmethod
|
||||
|
||||
// ----------------
|
||||
@@ -360,34 +361,34 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
|
||||
|
||||
method ActionValue #(DM_Word) av_read (DM_Addr dm_addr);
|
||||
actionvalue
|
||||
DM_Word dm_word = case (dm_addr)
|
||||
dm_addr_dmcontrol: virt_rg_dmcontrol;
|
||||
dm_addr_dmstatus: virt_rg_dmstatus;
|
||||
dm_addr_haltsum: haltsum;
|
||||
dm_addr_haltregion0: haltregion0;
|
||||
dm_addr_verbosity: extend (rg_verbosity);
|
||||
endcase;
|
||||
DM_Word dm_word = case (dm_addr)
|
||||
dm_addr_dmcontrol: virt_rg_dmcontrol;
|
||||
dm_addr_dmstatus: virt_rg_dmstatus;
|
||||
dm_addr_haltsum: haltsum;
|
||||
dm_addr_haltregion0: haltregion0;
|
||||
dm_addr_verbosity: extend (rg_verbosity);
|
||||
endcase;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.av_read: [", cur_cycle, fshow_dm_addr (dm_addr), "] => 0x%08h", dm_word);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.av_read: [", cur_cycle, fshow_dm_addr (dm_addr), "] => 0x%08h", dm_word);
|
||||
|
||||
return dm_word;
|
||||
return dm_word;
|
||||
endactionvalue
|
||||
endmethod
|
||||
|
||||
method Action write (DM_Addr dm_addr, DM_Word dm_word);
|
||||
action
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.write: [", cur_cycle, fshow_dm_addr (dm_addr), "] <= 0x%08h", dm_word);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.write: [", cur_cycle, fshow_dm_addr (dm_addr), "] <= 0x%08h", dm_word);
|
||||
|
||||
case (dm_addr)
|
||||
dm_addr_dmcontrol: fa_rg_dmcontrol_write (dm_word);
|
||||
dm_addr_verbosity: begin
|
||||
rg_verbosity <= truncate (dm_word);
|
||||
f_hart0_other_reqs.enq (truncate (dm_word));
|
||||
end
|
||||
default: noAction;
|
||||
endcase
|
||||
case (dm_addr)
|
||||
dm_addr_dmcontrol: fa_rg_dmcontrol_write (dm_word);
|
||||
dm_addr_verbosity: begin
|
||||
rg_verbosity <= truncate (dm_word);
|
||||
f_hart0_other_reqs.enq (truncate (dm_word));
|
||||
end
|
||||
default: noAction;
|
||||
endcase
|
||||
endaction
|
||||
endmethod
|
||||
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
// Copyright (c) 2017-2019 Bluespec, Inc. All Rights Reserved.
|
||||
|
||||
//-
|
||||
// AXI (user fields) modifications:
|
||||
// Copyright (c) 2019 Alexandre Joannou
|
||||
// Copyright (c) 2019 Peter Rugg
|
||||
// Copyright (c) 2019 Jonathan Woodruff
|
||||
// All rights reserved.
|
||||
//
|
||||
// This software was developed by SRI International and the University of
|
||||
// Cambridge Computer Laboratory (Department of Computer Science and
|
||||
// Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
|
||||
// DARPA SSITH research programme.
|
||||
//-
|
||||
|
||||
package DM_System_Bus;
|
||||
|
||||
// ================================================================
|
||||
@@ -15,6 +28,8 @@ import FIFOF :: *;
|
||||
// Other library imports
|
||||
|
||||
import Semi_FIFOF :: *;
|
||||
import SourceSink :: *;
|
||||
import AXI4 :: *;
|
||||
|
||||
// ================================================================
|
||||
// Project Imports
|
||||
@@ -22,7 +37,6 @@ import Semi_FIFOF :: *;
|
||||
import ISA_Decls :: *;
|
||||
import DM_Common :: *;
|
||||
|
||||
import AXI4_Types :: *;
|
||||
import Fabric_Defs :: *;
|
||||
|
||||
// ================================================================
|
||||
@@ -38,7 +52,9 @@ interface DM_System_Bus_IFC;
|
||||
|
||||
// ----------------
|
||||
// Facing System
|
||||
interface AXI4_Master_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) master;
|
||||
interface AXI4_Master_Synth #(Wd_MId_2x3, Wd_Addr, Wd_Data_Periph,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User) master;
|
||||
endinterface
|
||||
|
||||
// ================================================================
|
||||
@@ -49,11 +65,11 @@ endinterface
|
||||
|
||||
function AXI4_Size fn_DM_sbaccess_to_AXI4_Size (DM_sbaccess sbaccess);
|
||||
AXI4_Size axi4_size = case (sbaccess)
|
||||
DM_SBACCESS_8_BIT: axsize_1;
|
||||
DM_SBACCESS_16_BIT: axsize_2;
|
||||
DM_SBACCESS_32_BIT: axsize_4;
|
||||
DM_SBACCESS_64_BIT: axsize_8;
|
||||
endcase;
|
||||
DM_SBACCESS_8_BIT: 1;
|
||||
DM_SBACCESS_16_BIT: 2;
|
||||
DM_SBACCESS_32_BIT: 4;
|
||||
DM_SBACCESS_64_BIT: 8;
|
||||
endcase;
|
||||
return axi4_size;
|
||||
endfunction
|
||||
|
||||
@@ -68,8 +84,8 @@ endfunction
|
||||
// - word with correct byte(s) shifted into LSBs and zero extended
|
||||
|
||||
function Bit #(64) fn_extract_and_extend_bytes (DM_sbaccess sbaccess,
|
||||
Bit #(64) read_addr,
|
||||
Bit #(64) word64);
|
||||
Bit #(64) read_addr,
|
||||
Bit #(64) word64);
|
||||
Bit #(3) addr_lsbs = read_addr [2:0];
|
||||
if (valueOf (Wd_Data) == 32)
|
||||
addr_lsbs = (addr_lsbs & 'h3);
|
||||
@@ -77,31 +93,31 @@ function Bit #(64) fn_extract_and_extend_bytes (DM_sbaccess sbaccess,
|
||||
Bit #(64) result = 0;
|
||||
case (sbaccess)
|
||||
DM_SBACCESS_8_BIT: case (addr_lsbs)
|
||||
'h0: result = zeroExtend (word64 [ 7: 0]);
|
||||
'h1: result = zeroExtend (word64 [15: 8]);
|
||||
'h2: result = zeroExtend (word64 [23:16]);
|
||||
'h3: result = zeroExtend (word64 [31:24]);
|
||||
'h4: result = zeroExtend (word64 [39:32]);
|
||||
'h5: result = zeroExtend (word64 [47:40]);
|
||||
'h6: result = zeroExtend (word64 [55:48]);
|
||||
'h7: result = zeroExtend (word64 [63:56]);
|
||||
endcase
|
||||
'h0: result = zeroExtend (word64 [ 7: 0]);
|
||||
'h1: result = zeroExtend (word64 [15: 8]);
|
||||
'h2: result = zeroExtend (word64 [23:16]);
|
||||
'h3: result = zeroExtend (word64 [31:24]);
|
||||
'h4: result = zeroExtend (word64 [39:32]);
|
||||
'h5: result = zeroExtend (word64 [47:40]);
|
||||
'h6: result = zeroExtend (word64 [55:48]);
|
||||
'h7: result = zeroExtend (word64 [63:56]);
|
||||
endcase
|
||||
|
||||
DM_SBACCESS_16_BIT: case (addr_lsbs)
|
||||
'h0: result = zeroExtend (word64 [15: 0]);
|
||||
'h2: result = zeroExtend (word64 [31:16]);
|
||||
'h4: result = zeroExtend (word64 [47:32]);
|
||||
'h6: result = zeroExtend (word64 [63:48]);
|
||||
endcase
|
||||
'h0: result = zeroExtend (word64 [15: 0]);
|
||||
'h2: result = zeroExtend (word64 [31:16]);
|
||||
'h4: result = zeroExtend (word64 [47:32]);
|
||||
'h6: result = zeroExtend (word64 [63:48]);
|
||||
endcase
|
||||
|
||||
DM_SBACCESS_32_BIT: case (addr_lsbs)
|
||||
'h0: result = zeroExtend (word64 [31: 0]);
|
||||
'h4: result = zeroExtend (word64 [63:32]);
|
||||
endcase
|
||||
'h0: result = zeroExtend (word64 [31: 0]);
|
||||
'h4: result = zeroExtend (word64 [63:32]);
|
||||
endcase
|
||||
|
||||
DM_SBACCESS_64_BIT: case (addr_lsbs)
|
||||
'h0: result = word64;
|
||||
endcase
|
||||
'h0: result = word64;
|
||||
endcase
|
||||
endcase
|
||||
return result;
|
||||
endfunction
|
||||
@@ -110,39 +126,39 @@ endfunction
|
||||
// Compute address, data and strobe (byte-enables) for writes to fabric
|
||||
|
||||
function Tuple4 #(Fabric_Addr, // addr is 32b- or 64b-aligned
|
||||
Fabric_Data, // data is lane-aligned
|
||||
Fabric_Strb, // strobe
|
||||
AXI4_Size) // 8 for 8-byte writes, else 4
|
||||
Fabric_Data_Periph, // data is lane-aligned
|
||||
Fabric_Strb_Periph, // strobe
|
||||
AXI4_Size) // 8 for 8-byte writes, else 4
|
||||
fn_to_fabric_write_fields (DM_sbaccess sbaccess, // size of access
|
||||
Bit #(64) addr,
|
||||
Bit #(64) word64); // data is in lsbs
|
||||
Bit #(64) addr,
|
||||
Bit #(64) word64); // data is in lsbs
|
||||
|
||||
// First compute addr, data and strobe for a 64b-wide fabric
|
||||
Bit #(8) strobe64 = 0;
|
||||
Bit #(3) shift_bytes = addr [2:0];
|
||||
Bit #(6) shift_bits = { shift_bytes, 3'b0 };
|
||||
AXI4_Size axsize = axsize_128; // Will be updated in 'case' below
|
||||
AXI4_Size axsize = 128; // Will be updated in 'case' below
|
||||
|
||||
case (sbaccess)
|
||||
DM_SBACCESS_8_BIT: begin
|
||||
word64 = (word64 << shift_bits);
|
||||
strobe64 = ('b_1 << shift_bytes);
|
||||
axsize = axsize_1;
|
||||
end
|
||||
word64 = (word64 << shift_bits);
|
||||
strobe64 = ('b_1 << shift_bytes);
|
||||
axsize = 1;
|
||||
end
|
||||
DM_SBACCESS_16_BIT: begin
|
||||
word64 = (word64 << shift_bits);
|
||||
strobe64 = ('b_11 << shift_bytes);
|
||||
axsize = axsize_2;
|
||||
end
|
||||
word64 = (word64 << shift_bits);
|
||||
strobe64 = ('b_11 << shift_bytes);
|
||||
axsize = 2;
|
||||
end
|
||||
DM_SBACCESS_32_BIT: begin
|
||||
word64 = (word64 << shift_bits);
|
||||
strobe64 = ('b_1111 << shift_bytes);
|
||||
axsize = axsize_4;
|
||||
end
|
||||
word64 = (word64 << shift_bits);
|
||||
strobe64 = ('b_1111 << shift_bytes);
|
||||
axsize = 4;
|
||||
end
|
||||
DM_SBACCESS_64_BIT: begin
|
||||
strobe64 = 'b_1111_1111;
|
||||
axsize = axsize_8;
|
||||
end
|
||||
strobe64 = 'b_1111_1111;
|
||||
axsize = 8;
|
||||
end
|
||||
endcase
|
||||
|
||||
// Adjust for 32b fabrics
|
||||
@@ -153,8 +169,8 @@ function Tuple4 #(Fabric_Addr, // addr is 32b- or 64b-aligned
|
||||
|
||||
// Finally, create fabric addr/data/strobe
|
||||
Fabric_Addr fabric_addr = truncate (addr);
|
||||
Fabric_Data fabric_data = truncate (word64);
|
||||
Fabric_Strb fabric_strobe = truncate (strobe64);
|
||||
Fabric_Data_Periph fabric_data = truncate (word64);
|
||||
Fabric_Strb_Periph fabric_strobe = truncate (strobe64);
|
||||
|
||||
return tuple4 (fabric_addr, fabric_data, fabric_strobe, axsize);
|
||||
endfunction: fn_to_fabric_write_fields
|
||||
@@ -163,8 +179,8 @@ endfunction: fn_to_fabric_write_fields
|
||||
// System Bus access states
|
||||
|
||||
typedef enum {SB_NOTBUSY,
|
||||
SB_READ_FINISH,
|
||||
SB_WRITE_FINISH
|
||||
SB_READ_FINISH,
|
||||
SB_WRITE_FINISH
|
||||
} SB_State
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
@@ -179,7 +195,10 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// Interface to memory fabric
|
||||
AXI4_Master_Xactor_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) master_xactor <- mkAXI4_Master_Xactor;
|
||||
AXI4_Master_Xactor#(Wd_MId_2x3, Wd_Addr, Wd_Data_Periph,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User)
|
||||
master_xactor <- mkAXI4_Master_Xactor;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// System Bus state
|
||||
@@ -218,25 +237,25 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
UInt #(3) sbversion = 1;
|
||||
|
||||
DM_Word virt_rg_sbcs = {pack (sbversion),
|
||||
6'b0,
|
||||
pack (rg_sbcs_sbbusyerror),
|
||||
pack (sbbusy),
|
||||
pack (rg_sbcs_sbreadonaddr),
|
||||
pack (rg_sbcs_sbaccess),
|
||||
pack (rg_sbcs_sbautoincrement),
|
||||
pack (rg_sbcs_sbreadondata),
|
||||
pack (rg_sbcs_sberror),
|
||||
6'b0,
|
||||
pack (rg_sbcs_sbbusyerror),
|
||||
pack (sbbusy),
|
||||
pack (rg_sbcs_sbreadonaddr),
|
||||
pack (rg_sbcs_sbaccess),
|
||||
pack (rg_sbcs_sbautoincrement),
|
||||
pack (rg_sbcs_sbreadondata),
|
||||
pack (rg_sbcs_sberror),
|
||||
`ifdef RV64
|
||||
7'd64, // sbasize -- address size
|
||||
7'd64, // sbasize -- address size
|
||||
`endif
|
||||
`ifdef RV32
|
||||
7'd32, // sbasize -- address size
|
||||
7'd32, // sbasize -- address size
|
||||
`endif
|
||||
1'b0, // sbaccess128
|
||||
1'b0, // sbaccess64
|
||||
1'b1, // sbaccess32
|
||||
1'b1, // sbaccess16
|
||||
1'b1}; // sbaccess8
|
||||
1'b0, // sbaccess128
|
||||
1'b0, // sbaccess64
|
||||
1'b1, // sbaccess32
|
||||
1'b1, // sbaccess16
|
||||
1'b1}; // sbaccess8
|
||||
|
||||
// ----------------
|
||||
// Local defs and help functions
|
||||
@@ -245,16 +264,16 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
function Action fa_sbaddress_incr (Bit #(64) addr64);
|
||||
action
|
||||
Bit #(64) next_sbaddress = addr64 + fromInteger (addr_incr);
|
||||
Bit #(64) next_sbaddress = addr64 + fromInteger (addr_incr);
|
||||
`ifdef RV64
|
||||
rg_sbaddress1 <= next_sbaddress [63:32];
|
||||
rg_sbaddress1 <= next_sbaddress [63:32];
|
||||
`else
|
||||
rg_sbaddress1 <= 0;
|
||||
rg_sbaddress1 <= 0;
|
||||
`endif
|
||||
rg_sbaddress0 <= next_sbaddress [31:0];
|
||||
rg_sbaddress0 <= next_sbaddress [31:0];
|
||||
|
||||
if (verbosity != 0)
|
||||
$display (" Increment sbaddr 0x%08h -> 0x%08h", addr64, next_sbaddress);
|
||||
if (verbosity != 0)
|
||||
$display (" Increment sbaddr 0x%08h -> 0x%08h", addr64, next_sbaddress);
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -263,30 +282,30 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
function Action fa_fabric_send_read_req (Bit #(64) addr64);
|
||||
action
|
||||
Fabric_Addr fabric_addr = truncate (addr64);
|
||||
let rda = AXI4_Rd_Addr {arid: fabric_default_id,
|
||||
araddr: fabric_addr,
|
||||
arlen: 0, // burst len = arlen+1
|
||||
arsize: fn_DM_sbaccess_to_AXI4_Size (rg_sbcs_sbaccess),
|
||||
arburst: fabric_default_burst,
|
||||
arlock: fabric_default_lock,
|
||||
arcache: fabric_default_arcache,
|
||||
arprot: fabric_default_prot,
|
||||
arqos: fabric_default_qos,
|
||||
arregion: fabric_default_region,
|
||||
aruser: fabric_default_user};
|
||||
master_xactor.i_rd_addr.enq (rda);
|
||||
Fabric_Addr fabric_addr = truncate (addr64);
|
||||
let rda = AXI4_ARFlit {arid: fabric_2x3_default_mid,
|
||||
araddr: fabric_addr,
|
||||
arlen: 0, // burst len = arlen+1
|
||||
arsize: fn_DM_sbaccess_to_AXI4_Size (rg_sbcs_sbaccess),
|
||||
arburst: fabric_default_burst,
|
||||
arlock: fabric_default_lock,
|
||||
arcache: fabric_default_arcache,
|
||||
arprot: fabric_default_prot,
|
||||
arqos: fabric_default_qos,
|
||||
arregion: fabric_default_region,
|
||||
aruser: fabric_default_aruser};
|
||||
master_xactor.slave.ar.put(rda);
|
||||
|
||||
// Save read-address for byte-lane extraction from later response
|
||||
// (since rg_sbaddress may be incremented by then).
|
||||
rg_sbaddress_reading <= addr64;
|
||||
// Save read-address for byte-lane extraction from later response
|
||||
// (since rg_sbaddress may be incremented by then).
|
||||
rg_sbaddress_reading <= addr64;
|
||||
|
||||
rg_sb_state <= SB_READ_FINISH;
|
||||
rg_sb_state <= SB_READ_FINISH;
|
||||
|
||||
if (verbosity != 0) begin
|
||||
$display (" DM_System_Bus.fa_fabric_send_read_req, and => SB_READ_FINISH ");
|
||||
$display (" ", fshow (rda));
|
||||
end
|
||||
if (verbosity != 0) begin
|
||||
$display (" DM_System_Bus.fa_fabric_send_read_req, and => SB_READ_FINISH ");
|
||||
$display (" ", fshow (rda));
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -295,40 +314,40 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
function Action fa_fabric_send_write_req (Bit #(64) data64);
|
||||
action
|
||||
match {.fabric_addr,
|
||||
.fabric_data,
|
||||
.fabric_strb,
|
||||
.fabric_size} = fn_to_fabric_write_fields (rg_sbcs_sbaccess, sbaddress, data64);
|
||||
|
||||
// fabric_addr is always fabric-data-width aligned
|
||||
// fabric_data is properly lane-adjusted
|
||||
// fabric_strb identifies the lanes to be written
|
||||
// awsize is always the fabric width
|
||||
match {.fabric_addr,
|
||||
.fabric_data,
|
||||
.fabric_strb,
|
||||
.fabric_size} = fn_to_fabric_write_fields (rg_sbcs_sbaccess, sbaddress, data64);
|
||||
|
||||
// fabric_addr is always fabric-data-width aligned
|
||||
// fabric_data is properly lane-adjusted
|
||||
// fabric_strb identifies the lanes to be written
|
||||
// awsize is always the fabric width
|
||||
|
||||
let wra = AXI4_Wr_Addr {awid: fabric_default_id,
|
||||
awaddr: fabric_addr,
|
||||
awlen: 0, // burst len = awlen+1
|
||||
awsize: fabric_size,
|
||||
awburst: fabric_default_burst,
|
||||
awlock: fabric_default_lock,
|
||||
awcache: fabric_default_awcache,
|
||||
awprot: fabric_default_prot,
|
||||
awqos: fabric_default_qos,
|
||||
awregion: fabric_default_region,
|
||||
awuser: fabric_default_user};
|
||||
master_xactor.i_wr_addr.enq (wra);
|
||||
let wra = AXI4_AWFlit {awid: fabric_2x3_default_mid,
|
||||
awaddr: fabric_addr,
|
||||
awlen: 0, // burst len = awlen+1
|
||||
awsize: fabric_size,
|
||||
awburst: fabric_default_burst,
|
||||
awlock: fabric_default_lock,
|
||||
awcache: fabric_default_awcache,
|
||||
awprot: fabric_default_prot,
|
||||
awqos: fabric_default_qos,
|
||||
awregion: fabric_default_region,
|
||||
awuser: fabric_default_awuser};
|
||||
master_xactor.slave.aw.put(wra);
|
||||
|
||||
let wrd = AXI4_Wr_Data {wdata: fabric_data,
|
||||
wstrb: fabric_strb,
|
||||
wlast: True,
|
||||
wuser: fabric_default_user};
|
||||
master_xactor.i_wr_data.enq (wrd);
|
||||
let wrd = AXI4_WFlit {wdata: fabric_data,
|
||||
wstrb: fabric_strb,
|
||||
wlast: True,
|
||||
wuser: fabric_default_wuser};
|
||||
master_xactor.slave.w.put(wrd);
|
||||
|
||||
if (verbosity != 0) begin
|
||||
$display (" DM_System_Bus.fa_fabric_send_write_req:");
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
end
|
||||
if (verbosity != 0) begin
|
||||
$display (" DM_System_Bus.fa_fabric_send_write_req:");
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -337,54 +356,54 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
function Action fa_rg_sbcs_write (DM_Word dm_word);
|
||||
action
|
||||
Bool sbbusyerror = unpack (dm_word [22]);
|
||||
Bool sbreadonaddr = unpack (dm_word [20]);
|
||||
DM_sbaccess sbaccess = unpack (dm_word [19:17]);
|
||||
Bool sbautoincrement = unpack (dm_word [16]);
|
||||
Bool sbreadondata = unpack (dm_word [15]);
|
||||
DM_sberror sberror = unpack (dm_word [14:12]);
|
||||
Bool sbbusyerror = unpack (dm_word [22]);
|
||||
Bool sbreadonaddr = unpack (dm_word [20]);
|
||||
DM_sbaccess sbaccess = unpack (dm_word [19:17]);
|
||||
Bool sbautoincrement = unpack (dm_word [16]);
|
||||
Bool sbreadondata = unpack (dm_word [15]);
|
||||
DM_sberror sberror = unpack (dm_word [14:12]);
|
||||
|
||||
// No-op if not clearing existing sberror
|
||||
if ((rg_sbcs_sberror != DM_SBERROR_NONE) && (sberror == DM_SBERROR_NONE)) begin
|
||||
// Existing error is not being cleared
|
||||
$display ("DM_System_Bus.sbcs_write <= 0x%08h: ERROR", dm_word);
|
||||
$display (" ERROR: existing sberror (0x%0h) is not being cleared.", rg_sbcs_sberror);
|
||||
$display (" Must be cleared to re-enable system bus access.");
|
||||
end
|
||||
// No-op if not clearing existing sberror
|
||||
if ((rg_sbcs_sberror != DM_SBERROR_NONE) && (sberror == DM_SBERROR_NONE)) begin
|
||||
// Existing error is not being cleared
|
||||
$display ("DM_System_Bus.sbcs_write <= 0x%08h: ERROR", dm_word);
|
||||
$display (" ERROR: existing sberror (0x%0h) is not being cleared.", rg_sbcs_sberror);
|
||||
$display (" Must be cleared to re-enable system bus access.");
|
||||
end
|
||||
|
||||
// No-op if not clearing existing sbbusyerror
|
||||
else if (rg_sbcs_sbbusyerror && (! sbbusyerror)) begin
|
||||
$display ("DM_System_Bus.sbcs_write <= 0x%08h: ERROR", dm_word);
|
||||
$display (" ERROR: existing sbbusyerror (%0d) is not being cleared.", rg_sbcs_sbbusyerror);
|
||||
$display (" Must be cleared to re-enable system bus access.");
|
||||
end
|
||||
// No-op if not clearing existing sbbusyerror
|
||||
else if (rg_sbcs_sbbusyerror && (! sbbusyerror)) begin
|
||||
$display ("DM_System_Bus.sbcs_write <= 0x%08h: ERROR", dm_word);
|
||||
$display (" ERROR: existing sbbusyerror (%0d) is not being cleared.", rg_sbcs_sbbusyerror);
|
||||
$display (" Must be cleared to re-enable system bus access.");
|
||||
end
|
||||
|
||||
// Check that requested access size is supported
|
||||
else if ( (sbaccess == DM_SBACCESS_128_BIT)
|
||||
|| (sbaccess == DM_SBACCESS_64_BIT))
|
||||
begin
|
||||
rg_sbcs_sberror <= DM_SBERROR_OTHER;
|
||||
$display ("DM_System_Bus.sbcs_write <= 0x%08h: ERROR", dm_word);
|
||||
$display (" ERROR: sbaccess ", fshow (sbaccess), " not supported");
|
||||
end
|
||||
// Check that requested access size is supported
|
||||
else if ( (sbaccess == DM_SBACCESS_128_BIT)
|
||||
|| (sbaccess == DM_SBACCESS_64_BIT))
|
||||
begin
|
||||
rg_sbcs_sberror <= DM_SBERROR_OTHER;
|
||||
$display ("DM_System_Bus.sbcs_write <= 0x%08h: ERROR", dm_word);
|
||||
$display (" ERROR: sbaccess ", fshow (sbaccess), " not supported");
|
||||
end
|
||||
|
||||
// Ok
|
||||
else begin
|
||||
if (verbosity != 0) begin
|
||||
$display (" DM_System_Bus.sbcs_write: ", fshow_sbcs (dm_word));
|
||||
if (rg_sbcs_sberror != DM_SBERROR_NONE)
|
||||
$display (" Clearing sbcs.sberror");
|
||||
if (rg_sbcs_sbbusyerror)
|
||||
$display (" Clearing sbcs.sbbusyerror");
|
||||
end
|
||||
// Ok
|
||||
else begin
|
||||
if (verbosity != 0) begin
|
||||
$display (" DM_System_Bus.sbcs_write: ", fshow_sbcs (dm_word));
|
||||
if (rg_sbcs_sberror != DM_SBERROR_NONE)
|
||||
$display (" Clearing sbcs.sberror");
|
||||
if (rg_sbcs_sbbusyerror)
|
||||
$display (" Clearing sbcs.sbbusyerror");
|
||||
end
|
||||
|
||||
rg_sbcs_sbbusyerror <= False;
|
||||
rg_sbcs_sbreadonaddr <= sbreadonaddr;
|
||||
rg_sbcs_sbaccess <= sbaccess;
|
||||
rg_sbcs_sbautoincrement <= sbautoincrement;
|
||||
rg_sbcs_sbreadondata <= sbreadondata;
|
||||
rg_sbcs_sberror <= DM_SBERROR_NONE;
|
||||
end
|
||||
rg_sbcs_sbbusyerror <= False;
|
||||
rg_sbcs_sbreadonaddr <= sbreadonaddr;
|
||||
rg_sbcs_sbaccess <= sbaccess;
|
||||
rg_sbcs_sbautoincrement <= sbautoincrement;
|
||||
rg_sbcs_sbreadondata <= sbreadondata;
|
||||
rg_sbcs_sberror <= DM_SBERROR_NONE;
|
||||
end
|
||||
endaction
|
||||
endfunction: fa_rg_sbcs_write
|
||||
|
||||
@@ -393,54 +412,54 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
function Action fa_rg_sbaddress_write (DM_Addr dm_addr, DM_Word dm_word);
|
||||
action
|
||||
// Debug announce
|
||||
if (verbosity != 0) begin
|
||||
$write ("DM_System_Bus.sbaddress.write: [0x%08h] <= 0x%08h", dm_addr, dm_word);
|
||||
if (rg_sbcs_sbreadonaddr) begin
|
||||
$write ("; readonaddr");
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
$write ("; autoincrement");
|
||||
end
|
||||
$display ("");
|
||||
end
|
||||
// Debug announce
|
||||
if (verbosity != 0) begin
|
||||
$write ("DM_System_Bus.sbaddress.write: [0x%08h] <= 0x%08h", dm_addr, dm_word);
|
||||
if (rg_sbcs_sbreadonaddr) begin
|
||||
$write ("; readonaddr");
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
$write ("; autoincrement");
|
||||
end
|
||||
$display ("");
|
||||
end
|
||||
|
||||
if (sbbusy) begin
|
||||
$display ("DM_System_Bus.sbaddress.write: busy, setting sbbusyerror");
|
||||
rg_sbcs_sbbusyerror <= True;
|
||||
end
|
||||
if (sbbusy) begin
|
||||
$display ("DM_System_Bus.sbaddress.write: busy, setting sbbusyerror");
|
||||
rg_sbcs_sbbusyerror <= True;
|
||||
end
|
||||
|
||||
else if (rg_sbcs_sbbusyerror)
|
||||
$display ("DM_System_Bus.sbaddress.write: ignoring due to sbbusyerror");
|
||||
else if (rg_sbcs_sbbusyerror)
|
||||
$display ("DM_System_Bus.sbaddress.write: ignoring due to sbbusyerror");
|
||||
|
||||
else if (rg_sbcs_sberror != DM_SBERROR_NONE)
|
||||
$display ("DM_System_Bus.sbaddress.write: ignoring due to sberror = 0x%0h",
|
||||
rg_sbcs_sberror);
|
||||
else if (rg_sbcs_sberror != DM_SBERROR_NONE)
|
||||
$display ("DM_System_Bus.sbaddress.write: ignoring due to sberror = 0x%0h",
|
||||
rg_sbcs_sberror);
|
||||
|
||||
else if (dm_addr == dm_addr_sbaddress0) begin
|
||||
Bit #(64) addr64 = { rg_sbaddress1, dm_word };
|
||||
if (rg_sbcs_sbreadonaddr) begin
|
||||
fa_fabric_send_read_req (addr64);
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
fa_sbaddress_incr (addr64);
|
||||
else
|
||||
rg_sbaddress0 <= dm_word;
|
||||
end
|
||||
else
|
||||
rg_sbaddress0 <= dm_word;
|
||||
end
|
||||
else if (dm_addr == dm_addr_sbaddress0) begin
|
||||
Bit #(64) addr64 = { rg_sbaddress1, dm_word };
|
||||
if (rg_sbcs_sbreadonaddr) begin
|
||||
fa_fabric_send_read_req (addr64);
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
fa_sbaddress_incr (addr64);
|
||||
else
|
||||
rg_sbaddress0 <= dm_word;
|
||||
end
|
||||
else
|
||||
rg_sbaddress0 <= dm_word;
|
||||
end
|
||||
|
||||
else begin // (dm_addr == dm_addr_sbaddress1)
|
||||
else begin // (dm_addr == dm_addr_sbaddress1)
|
||||
`ifdef RV32
|
||||
rg_sbaddress1 <= 0;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.write: [sbaddress1] <= 0 (RV32: ignoring arg value 0x%08h)",
|
||||
dm_word);
|
||||
rg_sbaddress1 <= 0;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.write: [sbaddress1] <= 0 (RV32: ignoring arg value 0x%08h)",
|
||||
dm_word);
|
||||
`else
|
||||
rg_sbaddress1 <= dm_word;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.write: [sbaddress1] <= 0x%08h", dm_word);
|
||||
rg_sbaddress1 <= dm_word;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.write: [sbaddress1] <= 0x%08h", dm_word);
|
||||
`endif
|
||||
end
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -449,35 +468,35 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
function ActionValue #(DM_Word) fav_rg_sbdata_read (DM_Addr dm_addr);
|
||||
actionvalue
|
||||
DM_Word result = 0;
|
||||
if (sbbusy) begin
|
||||
$display ("DM_System_Bus.sbdata.read: busy, setting sbbusyerror");
|
||||
rg_sbcs_sbbusyerror <= True;
|
||||
end
|
||||
DM_Word result = 0;
|
||||
if (sbbusy) begin
|
||||
$display ("DM_System_Bus.sbdata.read: busy, setting sbbusyerror");
|
||||
rg_sbcs_sbbusyerror <= True;
|
||||
end
|
||||
|
||||
else if (rg_sbcs_sbbusyerror)
|
||||
$display ("DM_System_Bus.sbdata.read: ignoring due to sbbusyerror");
|
||||
else if (rg_sbcs_sbbusyerror)
|
||||
$display ("DM_System_Bus.sbdata.read: ignoring due to sbbusyerror");
|
||||
|
||||
else if (rg_sbcs_sberror != DM_SBERROR_NONE)
|
||||
$display ("DM_System_Bus.sbdata.read: ignoring due to sberror = 0x%0h", rg_sbcs_sberror);
|
||||
else if (rg_sbcs_sberror != DM_SBERROR_NONE)
|
||||
$display ("DM_System_Bus.sbdata.read: ignoring due to sberror = 0x%0h", rg_sbcs_sberror);
|
||||
|
||||
else begin
|
||||
if (dm_addr == dm_addr_sbdata0)
|
||||
result = rg_sbdata0;
|
||||
/* FUTURE: when supporting DM_SBACCESS_64_BIT
|
||||
else if (dm_addr == dm_addr_sbdata1)
|
||||
result = rg_sbdata1;
|
||||
*/
|
||||
else begin
|
||||
if (dm_addr == dm_addr_sbdata0)
|
||||
result = rg_sbdata0;
|
||||
/* FUTURE: when supporting DM_SBACCESS_64_BIT
|
||||
else if (dm_addr == dm_addr_sbdata1)
|
||||
result = rg_sbdata1;
|
||||
*/
|
||||
|
||||
// Increment sbaddress if needed
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
fa_sbaddress_incr (sbaddress);
|
||||
// Increment sbaddress if needed
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
fa_sbaddress_incr (sbaddress);
|
||||
|
||||
// Auto-read next data if needed
|
||||
if (rg_sbcs_sbreadondata && (dm_addr == dm_addr_sbdata0))
|
||||
fa_fabric_send_read_req (sbaddress);
|
||||
end
|
||||
return result;
|
||||
// Auto-read next data if needed
|
||||
if (rg_sbcs_sbreadondata && (dm_addr == dm_addr_sbdata0))
|
||||
fa_fabric_send_read_req (sbaddress);
|
||||
end
|
||||
return result;
|
||||
endactionvalue
|
||||
endfunction
|
||||
|
||||
@@ -487,19 +506,24 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
(* descending_urgency = "rl_sb_read_finish, reset" *)
|
||||
(* descending_urgency = "rl_sb_read_finish, write" *)
|
||||
rule rl_sb_read_finish ( (rg_sb_state == SB_READ_FINISH)
|
||||
&& (rg_sbcs_sberror == DM_SBERROR_NONE));
|
||||
let rdr <- pop_o (master_xactor.o_rd_data);
|
||||
&& (rg_sbcs_sberror == DM_SBERROR_NONE));
|
||||
let rdr <- get(master_xactor.slave.r);
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.rule_sb_read_finish: rdr = ", fshow (rdr));
|
||||
$display ("DM_System_Bus.rule_sb_read_finish: rdr = ", fshow (rdr));
|
||||
|
||||
// Extract relevant bytes from fabric data
|
||||
`ifdef ISA_CHERI
|
||||
Bit #(64) rdata64 = truncate (rdr.rdata);
|
||||
Bit #(64) data = fn_extract_and_extend_bytes (rg_sbcs_sbaccess, rg_sbaddress_reading, rdata64);
|
||||
`else
|
||||
Bit #(64) rdata64 = zeroExtend (rdr.rdata);
|
||||
Bit #(64) data = fn_extract_and_extend_bytes (rg_sbcs_sbaccess, rg_sbaddress_reading, rdata64);
|
||||
`endif
|
||||
|
||||
if (rdr.rresp != axi4_resp_okay) begin
|
||||
$display ("DM_System_Bus.rule_sb_read_finish: setting rg_sbcs_sberror to DM_SBERROR_OTHER\n");
|
||||
$display (" rdr = ", fshow (rdr));
|
||||
rg_sbcs_sberror <= DM_SBERROR_OTHER;
|
||||
if (rdr.rresp != OKAY) begin
|
||||
$display ("DM_System_Bus.rule_sb_read_finish: setting rg_sbcs_sberror to DM_SBERROR_OTHER\n");
|
||||
$display (" rdr = ", fshow (rdr));
|
||||
rg_sbcs_sberror <= DM_SBERROR_OTHER;
|
||||
end
|
||||
|
||||
rg_sbdata0 <= data [31:0];
|
||||
@@ -508,10 +532,10 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
*/
|
||||
|
||||
if (verbosity != 0) begin
|
||||
$display ("DM_System_Bus.rule_sb_read_finish: addr 0x%0h, sbaccess %0d (%0d bytes)",
|
||||
rg_sbaddress_reading, rg_sbcs_sbaccess, addr_incr);
|
||||
$display (" rg_sbdata0 <= 0x%0h", data);
|
||||
$display (" module state => SB_NOTBUSY");
|
||||
$display ("DM_System_Bus.rule_sb_read_finish: addr 0x%0h, sbaccess %0d (%0d bytes)",
|
||||
rg_sbaddress_reading, rg_sbcs_sbaccess, addr_incr);
|
||||
$display (" rg_sbdata0 <= 0x%0h", data);
|
||||
$display (" module state => SB_NOTBUSY");
|
||||
end
|
||||
|
||||
rg_sb_state <= SB_NOTBUSY;
|
||||
@@ -522,41 +546,41 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
function Action fa_rg_sbdata_write (DM_Addr dm_addr, DM_Word dm_word);
|
||||
action
|
||||
if (sbbusy) begin
|
||||
$display ("DM_System_Bus.sbdata.write: busy, setting sbbusyerror");
|
||||
rg_sbcs_sbbusyerror <= True;
|
||||
end
|
||||
if (sbbusy) begin
|
||||
$display ("DM_System_Bus.sbdata.write: busy, setting sbbusyerror");
|
||||
rg_sbcs_sbbusyerror <= True;
|
||||
end
|
||||
|
||||
else if (rg_sbcs_sbbusyerror) begin
|
||||
$display ("DM_System_Bus.sbdata.write: ignoring due to sbbusyerror");
|
||||
end
|
||||
else if (rg_sbcs_sbbusyerror) begin
|
||||
$display ("DM_System_Bus.sbdata.write: ignoring due to sbbusyerror");
|
||||
end
|
||||
|
||||
else if (rg_sbcs_sberror != DM_SBERROR_NONE) begin
|
||||
$display ("DM_System_Bus.sbdata.write: ignoring due to sberror = 0x%0h",
|
||||
rg_sbcs_sberror);
|
||||
end
|
||||
else if (rg_sbcs_sberror != DM_SBERROR_NONE) begin
|
||||
$display ("DM_System_Bus.sbdata.write: ignoring due to sberror = 0x%0h",
|
||||
rg_sbcs_sberror);
|
||||
end
|
||||
|
||||
else begin
|
||||
if (verbosity != 0)
|
||||
$display (" DM_System_Bus.fa_rg_sbdata_write: dm_addr 0x%08h dm_word 0x%08h",
|
||||
dm_addr, dm_word);
|
||||
else begin
|
||||
if (verbosity != 0)
|
||||
$display (" DM_System_Bus.fa_rg_sbdata_write: dm_addr 0x%08h dm_word 0x%08h",
|
||||
dm_addr, dm_word);
|
||||
|
||||
if (dm_addr == dm_addr_sbdata0)
|
||||
rg_sbdata0 <= dm_word;
|
||||
/* FUTURE: when supporting DM_SBACCESS_64_BIT
|
||||
else if (dm_addr == dm_addr_sbdata1)
|
||||
rg_sbdata1 <= dm_word;
|
||||
*/
|
||||
if (dm_addr == dm_addr_sbdata0)
|
||||
rg_sbdata0 <= dm_word;
|
||||
/* FUTURE: when supporting DM_SBACCESS_64_BIT
|
||||
else if (dm_addr == dm_addr_sbdata1)
|
||||
rg_sbdata1 <= dm_word;
|
||||
*/
|
||||
|
||||
// Initiate system bus write if writing to sbdata0
|
||||
if (dm_addr == dm_addr_sbdata0) begin
|
||||
fa_fabric_send_write_req (zeroExtend (dm_word));
|
||||
// Initiate system bus write if writing to sbdata0
|
||||
if (dm_addr == dm_addr_sbdata0) begin
|
||||
fa_fabric_send_write_req (zeroExtend (dm_word));
|
||||
|
||||
// Increment sbaddr ifneeded
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
fa_sbaddress_incr (sbaddress);
|
||||
end
|
||||
end
|
||||
// Increment sbaddr ifneeded
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
fa_sbaddress_incr (sbaddress);
|
||||
end
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -564,16 +588,16 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
// Consume write-responses
|
||||
|
||||
rule rl_sb_write_response;
|
||||
let wrr <- pop_o (master_xactor.o_wr_resp);
|
||||
if (wrr.bresp != axi4_resp_okay)
|
||||
rg_sbcs_sberror <= DM_SBERROR_OTHER;
|
||||
let wrr <- get(master_xactor.slave.b);
|
||||
if (wrr.bresp != OKAY)
|
||||
rg_sbcs_sberror <= DM_SBERROR_OTHER;
|
||||
endrule
|
||||
|
||||
// ================================================================
|
||||
// INTERFACE
|
||||
|
||||
method Action reset;
|
||||
// master_xactor.reset; // TODO: introduces a scheduling cycle: fix this
|
||||
master_xactor.clear;
|
||||
|
||||
rg_sb_state <= SB_NOTBUSY;
|
||||
|
||||
@@ -589,7 +613,7 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
rg_sbdata0 <= 0;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus: reset");
|
||||
$display ("DM_System_Bus: reset");
|
||||
endmethod
|
||||
|
||||
// ----------------
|
||||
@@ -600,61 +624,61 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
// workable for a true JTAG transport.
|
||||
method ActionValue #(DM_Word) av_read (DM_Addr dm_addr) if (!sbbusy);
|
||||
actionvalue
|
||||
DM_Word dm_word = 0;
|
||||
DM_Word dm_word = 0;
|
||||
|
||||
if (dm_addr == dm_addr_sbcs) begin
|
||||
dm_word = virt_rg_sbcs;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.read: [sbcs] => ", fshow_sbcs (dm_word));
|
||||
end
|
||||
if (dm_addr == dm_addr_sbcs) begin
|
||||
dm_word = virt_rg_sbcs;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.read: [sbcs] => ", fshow_sbcs (dm_word));
|
||||
end
|
||||
|
||||
else if (dm_addr == dm_addr_sbaddress0) begin
|
||||
dm_word = rg_sbaddress0;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.read: [sbaddress0] => 0x%08h", dm_word);
|
||||
end
|
||||
else if (dm_addr == dm_addr_sbaddress0) begin
|
||||
dm_word = rg_sbaddress0;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.read: [sbaddress0] => 0x%08h", dm_word);
|
||||
end
|
||||
|
||||
else if (dm_addr == dm_addr_sbaddress1) begin
|
||||
dm_word = rg_sbaddress1;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.read: [sbaddress1] => 0x%08h", dm_word);
|
||||
end
|
||||
else if (dm_addr == dm_addr_sbaddress1) begin
|
||||
dm_word = rg_sbaddress1;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.read: [sbaddress1] => 0x%08h", dm_word);
|
||||
end
|
||||
|
||||
else if (dm_addr == dm_addr_sbdata0) begin
|
||||
dm_word <- fav_rg_sbdata_read (dm_addr_sbdata0);
|
||||
end
|
||||
else if (dm_addr == dm_addr_sbdata0) begin
|
||||
dm_word <- fav_rg_sbdata_read (dm_addr_sbdata0);
|
||||
end
|
||||
|
||||
else begin
|
||||
// Unsupported dm address
|
||||
dm_word = 0;
|
||||
$display ("DM_System_Bus.read: [", fshow_dm_addr (dm_addr), "] not supported");
|
||||
end
|
||||
return dm_word;
|
||||
else begin
|
||||
// Unsupported dm address
|
||||
dm_word = 0;
|
||||
$display ("DM_System_Bus.read: [", fshow_dm_addr (dm_addr), "] not supported");
|
||||
end
|
||||
return dm_word;
|
||||
endactionvalue
|
||||
endmethod
|
||||
|
||||
method Action write (DM_Addr dm_addr, DM_Word dm_word);
|
||||
action
|
||||
if (dm_addr == dm_addr_sbcs)
|
||||
if (dm_addr == dm_addr_sbcs)
|
||||
fa_rg_sbcs_write (dm_word);
|
||||
|
||||
else if ((dm_addr == dm_addr_sbaddress0) || (dm_addr == dm_addr_sbaddress1))
|
||||
fa_rg_sbaddress_write (dm_addr, dm_word);
|
||||
else if ((dm_addr == dm_addr_sbaddress0) || (dm_addr == dm_addr_sbaddress1))
|
||||
fa_rg_sbaddress_write (dm_addr, dm_word);
|
||||
|
||||
else if (dm_addr == dm_addr_sbdata0) // FUTURE: || (dm_addr == dm_addr_sbdata1)
|
||||
fa_rg_sbdata_write (dm_addr, dm_word);
|
||||
else if (dm_addr == dm_addr_sbdata0) // FUTURE: || (dm_addr == dm_addr_sbdata1)
|
||||
fa_rg_sbdata_write (dm_addr, dm_word);
|
||||
|
||||
else begin
|
||||
// Unsupported dm_addr
|
||||
let addr_name = fshow_dm_addr (dm_addr);
|
||||
$display ("DM_System_Bus.write: [", addr_name, "] <= 0x%08h; addr not supported", dm_word);
|
||||
end
|
||||
else begin
|
||||
// Unsupported dm_addr
|
||||
let addr_name = fshow_dm_addr (dm_addr);
|
||||
$display ("DM_System_Bus.write: [", addr_name, "] <= 0x%08h; addr not supported", dm_word);
|
||||
end
|
||||
endaction
|
||||
endmethod
|
||||
|
||||
// ----------------
|
||||
// Facing System
|
||||
interface AXI4_Master_IFC master = master_xactor.axi_side;
|
||||
interface AXI4_Master_IFC master = master_xactor.masterSynth;
|
||||
endmodule
|
||||
|
||||
// ================================================================
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
// Copyright (c) 2017-2019 Bluespec, Inc. All Rights Reserved.
|
||||
|
||||
//-
|
||||
// AXI (user fields) modifications:
|
||||
// Copyright (c) 2019 Alexandre Joannou
|
||||
// Copyright (c) 2019 Peter Rugg
|
||||
// Copyright (c) 2019 Jonathan Woodruff
|
||||
// All rights reserved.
|
||||
//
|
||||
// This software was developed by SRI International and the University of
|
||||
// Cambridge Computer Laboratory (Department of Computer Science and
|
||||
// Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
|
||||
// DARPA SSITH research programme.
|
||||
//-
|
||||
|
||||
package Debug_Module;
|
||||
|
||||
// ================================================================
|
||||
@@ -52,7 +65,7 @@ package Debug_Module;
|
||||
// BSV library imports
|
||||
|
||||
import Memory :: *;
|
||||
import FIFOF :: *;
|
||||
import FIFO :: *;
|
||||
import GetPut :: *;
|
||||
import ClientServer :: *;
|
||||
import SpecialFIFOs :: *;
|
||||
@@ -62,12 +75,12 @@ import SpecialFIFOs :: *;
|
||||
|
||||
import Semi_FIFOF :: *;
|
||||
import Cur_Cycle :: *;
|
||||
import AXI4 :: *;
|
||||
|
||||
// ================================================================
|
||||
// Project imports
|
||||
|
||||
import ISA_Decls :: *;
|
||||
import AXI4_Types :: *;
|
||||
import Fabric_Defs :: *;
|
||||
|
||||
import DM_Common :: *;
|
||||
@@ -119,7 +132,9 @@ interface Debug_Module_IFC;
|
||||
interface Client #(Bool, Bool) ndm_reset_client;
|
||||
|
||||
// Read/Write RISC-V memory
|
||||
interface AXI4_Master_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) master;
|
||||
interface AXI4_Master_Synth #(Wd_MId_2x3, Wd_Addr, Wd_Data_Periph,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User) master;
|
||||
endinterface
|
||||
|
||||
// ================================================================
|
||||
@@ -135,7 +150,7 @@ module mkDebug_Module (Debug_Module_IFC);
|
||||
DM_Abstract_Commands_IFC dm_abstract_commands <- mkDM_Abstract_Commands;
|
||||
DM_System_Bus_IFC dm_system_bus <- mkDM_System_Bus;
|
||||
|
||||
FIFOF#(DM_Addr) f_read_addr <- mkBypassFIFOF;
|
||||
FIFO#(DM_Addr) f_read_addr <- mkFIFO1;
|
||||
|
||||
// ================================================================
|
||||
// Reset all three parts when dm_run_control.dmactive is low
|
||||
@@ -154,128 +169,128 @@ module mkDebug_Module (Debug_Module_IFC);
|
||||
// Facing GDB/DMI (Debug Module Interface)
|
||||
|
||||
interface DMI dmi;
|
||||
method Action read_addr (DM_Addr dm_addr);
|
||||
f_read_addr.enq(dm_addr);
|
||||
method Action read_addr (DM_Addr dm_addr) if (dm_run_control.dmactive);
|
||||
f_read_addr.enq(dm_addr);
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.DMI read: dm_addr 0x%0h", cur_cycle, dm_addr);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.DMI read: dm_addr 0x%0h", cur_cycle, dm_addr);
|
||||
endmethod
|
||||
|
||||
method ActionValue #(DM_Word) read_data;
|
||||
let dm_addr = f_read_addr.first;
|
||||
f_read_addr.deq;
|
||||
let dm_addr = f_read_addr.first;
|
||||
f_read_addr.deq;
|
||||
|
||||
DM_Word dm_word = ?;
|
||||
DM_Word dm_word = ?;
|
||||
|
||||
if ( (dm_addr == dm_addr_dmcontrol)
|
||||
|| (dm_addr == dm_addr_dmstatus)
|
||||
|| (dm_addr == dm_addr_hartinfo)
|
||||
|| (dm_addr == dm_addr_haltsum)
|
||||
|| (dm_addr == dm_addr_hawindowsel)
|
||||
|| (dm_addr == dm_addr_hawindow)
|
||||
|| (dm_addr == dm_addr_devtreeaddr0)
|
||||
|| (dm_addr == dm_addr_authdata)
|
||||
|| (dm_addr == dm_addr_haltregion0)
|
||||
|| (dm_addr == dm_addr_haltregion31)
|
||||
|| (dm_addr == dm_addr_verbosity))
|
||||
if ( (dm_addr == dm_addr_dmcontrol)
|
||||
|| (dm_addr == dm_addr_dmstatus)
|
||||
|| (dm_addr == dm_addr_hartinfo)
|
||||
|| (dm_addr == dm_addr_haltsum)
|
||||
|| (dm_addr == dm_addr_hawindowsel)
|
||||
|| (dm_addr == dm_addr_hawindow)
|
||||
|| (dm_addr == dm_addr_devtreeaddr0)
|
||||
|| (dm_addr == dm_addr_authdata)
|
||||
|| (dm_addr == dm_addr_haltregion0)
|
||||
|| (dm_addr == dm_addr_haltregion31)
|
||||
|| (dm_addr == dm_addr_verbosity))
|
||||
|
||||
dm_word <- dm_run_control.av_read (dm_addr);
|
||||
dm_word <- dm_run_control.av_read (dm_addr);
|
||||
|
||||
else if ( (dm_addr == dm_addr_abstractcs)
|
||||
|| (dm_addr == dm_addr_command)
|
||||
|| (dm_addr == dm_addr_data0)
|
||||
|| (dm_addr == dm_addr_data1)
|
||||
|| (dm_addr == dm_addr_data2)
|
||||
|| (dm_addr == dm_addr_data3)
|
||||
|| (dm_addr == dm_addr_data4)
|
||||
|| (dm_addr == dm_addr_data5)
|
||||
|| (dm_addr == dm_addr_data6)
|
||||
|| (dm_addr == dm_addr_data7)
|
||||
|| (dm_addr == dm_addr_data8)
|
||||
|| (dm_addr == dm_addr_data9)
|
||||
|| (dm_addr == dm_addr_data10)
|
||||
|| (dm_addr == dm_addr_data11)
|
||||
|| (dm_addr == dm_addr_abstractauto)
|
||||
|| (dm_addr == dm_addr_progbuf0))
|
||||
else if ( (dm_addr == dm_addr_abstractcs)
|
||||
|| (dm_addr == dm_addr_command)
|
||||
|| (dm_addr == dm_addr_data0)
|
||||
|| (dm_addr == dm_addr_data1)
|
||||
|| (dm_addr == dm_addr_data2)
|
||||
|| (dm_addr == dm_addr_data3)
|
||||
|| (dm_addr == dm_addr_data4)
|
||||
|| (dm_addr == dm_addr_data5)
|
||||
|| (dm_addr == dm_addr_data6)
|
||||
|| (dm_addr == dm_addr_data7)
|
||||
|| (dm_addr == dm_addr_data8)
|
||||
|| (dm_addr == dm_addr_data9)
|
||||
|| (dm_addr == dm_addr_data10)
|
||||
|| (dm_addr == dm_addr_data11)
|
||||
|| (dm_addr == dm_addr_abstractauto)
|
||||
|| (dm_addr == dm_addr_progbuf0))
|
||||
|
||||
dm_word <- dm_abstract_commands.av_read (dm_addr);
|
||||
dm_word <- dm_abstract_commands.av_read (dm_addr);
|
||||
|
||||
else if ( (dm_addr == dm_addr_sbcs)
|
||||
|| (dm_addr == dm_addr_sbaddress0)
|
||||
|| (dm_addr == dm_addr_sbaddress1)
|
||||
|| (dm_addr == dm_addr_sbaddress2)
|
||||
|| (dm_addr == dm_addr_sbdata0)
|
||||
|| (dm_addr == dm_addr_sbdata1)
|
||||
|| (dm_addr == dm_addr_sbdata2)
|
||||
|| (dm_addr == dm_addr_sbdata3))
|
||||
else if ( (dm_addr == dm_addr_sbcs)
|
||||
|| (dm_addr == dm_addr_sbaddress0)
|
||||
|| (dm_addr == dm_addr_sbaddress1)
|
||||
|| (dm_addr == dm_addr_sbaddress2)
|
||||
|| (dm_addr == dm_addr_sbdata0)
|
||||
|| (dm_addr == dm_addr_sbdata1)
|
||||
|| (dm_addr == dm_addr_sbdata2)
|
||||
|| (dm_addr == dm_addr_sbdata3))
|
||||
|
||||
dm_word <- dm_system_bus.av_read (dm_addr);
|
||||
dm_word <- dm_system_bus.av_read (dm_addr);
|
||||
|
||||
else begin
|
||||
// TODO: set error status?
|
||||
dm_word = 0;
|
||||
end
|
||||
else begin
|
||||
// TODO: set error status?
|
||||
dm_word = 0;
|
||||
end
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.DMI read response: dm_addr 0x%0h, dm_word 0x%0h",
|
||||
cur_cycle, dm_addr, dm_word);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.DMI read response: dm_addr 0x%0h, dm_word 0x%0h",
|
||||
cur_cycle, dm_addr, dm_word);
|
||||
|
||||
return dm_word;
|
||||
return dm_word;
|
||||
endmethod
|
||||
|
||||
method Action write (DM_Addr dm_addr, DM_Word dm_word);
|
||||
if ( (dm_addr == dm_addr_dmcontrol)
|
||||
|| (dm_addr == dm_addr_dmstatus)
|
||||
|| (dm_addr == dm_addr_hartinfo)
|
||||
|| (dm_addr == dm_addr_haltsum)
|
||||
|| (dm_addr == dm_addr_hawindowsel)
|
||||
|| (dm_addr == dm_addr_hawindow)
|
||||
|| (dm_addr == dm_addr_devtreeaddr0)
|
||||
|| (dm_addr == dm_addr_authdata)
|
||||
|| (dm_addr == dm_addr_haltregion0)
|
||||
|| (dm_addr == dm_addr_haltregion31)
|
||||
|| (dm_addr == dm_addr_verbosity))
|
||||
method Action write (DM_Addr dm_addr, DM_Word dm_word) if (dm_run_control.dmactive);
|
||||
if ( (dm_addr == dm_addr_dmcontrol)
|
||||
|| (dm_addr == dm_addr_dmstatus)
|
||||
|| (dm_addr == dm_addr_hartinfo)
|
||||
|| (dm_addr == dm_addr_haltsum)
|
||||
|| (dm_addr == dm_addr_hawindowsel)
|
||||
|| (dm_addr == dm_addr_hawindow)
|
||||
|| (dm_addr == dm_addr_devtreeaddr0)
|
||||
|| (dm_addr == dm_addr_authdata)
|
||||
|| (dm_addr == dm_addr_haltregion0)
|
||||
|| (dm_addr == dm_addr_haltregion31)
|
||||
|| (dm_addr == dm_addr_verbosity))
|
||||
|
||||
dm_run_control.write (dm_addr, dm_word);
|
||||
dm_run_control.write (dm_addr, dm_word);
|
||||
|
||||
else if ( (dm_addr == dm_addr_abstractcs)
|
||||
|| (dm_addr == dm_addr_command)
|
||||
|| (dm_addr == dm_addr_data0)
|
||||
|| (dm_addr == dm_addr_data1)
|
||||
|| (dm_addr == dm_addr_data2)
|
||||
|| (dm_addr == dm_addr_data3)
|
||||
|| (dm_addr == dm_addr_data4)
|
||||
|| (dm_addr == dm_addr_data5)
|
||||
|| (dm_addr == dm_addr_data6)
|
||||
|| (dm_addr == dm_addr_data7)
|
||||
|| (dm_addr == dm_addr_data8)
|
||||
|| (dm_addr == dm_addr_data9)
|
||||
|| (dm_addr == dm_addr_data10)
|
||||
|| (dm_addr == dm_addr_data11)
|
||||
|| (dm_addr == dm_addr_abstractauto)
|
||||
|| (dm_addr == dm_addr_progbuf0))
|
||||
else if ( (dm_addr == dm_addr_abstractcs)
|
||||
|| (dm_addr == dm_addr_command)
|
||||
|| (dm_addr == dm_addr_data0)
|
||||
|| (dm_addr == dm_addr_data1)
|
||||
|| (dm_addr == dm_addr_data2)
|
||||
|| (dm_addr == dm_addr_data3)
|
||||
|| (dm_addr == dm_addr_data4)
|
||||
|| (dm_addr == dm_addr_data5)
|
||||
|| (dm_addr == dm_addr_data6)
|
||||
|| (dm_addr == dm_addr_data7)
|
||||
|| (dm_addr == dm_addr_data8)
|
||||
|| (dm_addr == dm_addr_data9)
|
||||
|| (dm_addr == dm_addr_data10)
|
||||
|| (dm_addr == dm_addr_data11)
|
||||
|| (dm_addr == dm_addr_abstractauto)
|
||||
|| (dm_addr == dm_addr_progbuf0))
|
||||
|
||||
dm_abstract_commands.write (dm_addr, dm_word);
|
||||
dm_abstract_commands.write (dm_addr, dm_word);
|
||||
|
||||
else if ( (dm_addr == dm_addr_sbcs)
|
||||
|| (dm_addr == dm_addr_sbaddress0)
|
||||
|| (dm_addr == dm_addr_sbaddress1)
|
||||
|| (dm_addr == dm_addr_sbaddress2)
|
||||
|| (dm_addr == dm_addr_sbdata0)
|
||||
|| (dm_addr == dm_addr_sbdata1)
|
||||
|| (dm_addr == dm_addr_sbdata2)
|
||||
|| (dm_addr == dm_addr_sbdata3))
|
||||
else if ( (dm_addr == dm_addr_sbcs)
|
||||
|| (dm_addr == dm_addr_sbaddress0)
|
||||
|| (dm_addr == dm_addr_sbaddress1)
|
||||
|| (dm_addr == dm_addr_sbaddress2)
|
||||
|| (dm_addr == dm_addr_sbdata0)
|
||||
|| (dm_addr == dm_addr_sbdata1)
|
||||
|| (dm_addr == dm_addr_sbdata2)
|
||||
|| (dm_addr == dm_addr_sbdata3))
|
||||
|
||||
dm_system_bus.write (dm_addr, dm_word);
|
||||
dm_system_bus.write (dm_addr, dm_word);
|
||||
|
||||
else begin
|
||||
// TODO: set error status?
|
||||
noAction;
|
||||
end
|
||||
else begin
|
||||
// TODO: set error status?
|
||||
noAction;
|
||||
end
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.DMI write: dm_addr 0x%0h, dm_word 0x%0h",
|
||||
cur_cycle, dm_addr, dm_word);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.DMI write: dm_addr 0x%0h, dm_word 0x%0h",
|
||||
cur_cycle, dm_addr, dm_word);
|
||||
endmethod
|
||||
endinterface
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@ module mkTestbench (Empty);
|
||||
|
||||
rule rl_count_cycles;
|
||||
if (rg_cycle == fromInteger (100)) begin
|
||||
$display ("Testench: stopping at cycle %0d", cycle_limit);
|
||||
$finish (0);
|
||||
$display ("Testench: stopping at cycle %0d", cycle_limit);
|
||||
$finish (0);
|
||||
end
|
||||
rg_cycle <= rg_cycle +1;
|
||||
endrule
|
||||
@@ -90,8 +90,8 @@ module mkTestbench (Empty);
|
||||
let rda <- pop_o (dm.master.fo_rda);
|
||||
let data = rda.addr + 2; // Bogus data, for now
|
||||
let rdr = TRX_RdR {trans_id: rda.trans_id,
|
||||
status : TRX_OKAY,
|
||||
data : data};
|
||||
status : TRX_OKAY,
|
||||
data : data};
|
||||
dm.master.fi_rdr.enq (rdr);
|
||||
$display ("Testbench: memory read [0x%08h] => 0x%08h", rda.addr, data);
|
||||
endrule
|
||||
@@ -100,7 +100,7 @@ module mkTestbench (Empty);
|
||||
let wra <- pop_o (dm.master.fo_wra);
|
||||
let wrd <- pop_o (dm.master.fo_wrd);
|
||||
let wrr = TRX_WrR {trans_id: wra.trans_id,
|
||||
status : TRX_OKAY};
|
||||
status : TRX_OKAY};
|
||||
dm.master.fi_wrr.enq (wrr);
|
||||
$display ("Testbench: memory write [0x%08h] <= 0x%08h", wra.addr, wrd.data);
|
||||
endrule
|
||||
@@ -114,34 +114,34 @@ module mkTestbench (Empty);
|
||||
function Stmt fn_stmt_read_reg (Bit #(16) regno);
|
||||
return
|
||||
seq
|
||||
$display ("----------------\nRead RISC-V reg");
|
||||
// Clear any prior error status
|
||||
dm.write (dm_addr_abstractcs, fn_mk_abstractcs (dm_cmderr_w1c));
|
||||
// Perform the read
|
||||
dm.write (dm_addr_command,
|
||||
fn_mk_command_access_reg (DM_COMMAND_ACCESS_REG_SIZE_LOWER32,
|
||||
False, // postexec
|
||||
True, // transfer
|
||||
False, // write
|
||||
regno));
|
||||
// Read status to check no error
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
while (fn_abstractcs_busy (rg_abstractcs)) seq
|
||||
$display ("Testbench: read reg: busy");
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
endseq
|
||||
if (fn_abstractcs_cmderr (rg_abstractcs) != DM_ABSTRACTCS_CMDERR_NONE)
|
||||
$display ("Testbench: read reg => ", fshow (fn_abstractcs_cmderr (rg_abstractcs)));
|
||||
else action
|
||||
let x <- dm.av_read (dm_addr_data0);
|
||||
$display ("Testbench: read reg => 0x%08h", x);
|
||||
endaction
|
||||
$display ("----------------\nRead RISC-V reg");
|
||||
// Clear any prior error status
|
||||
dm.write (dm_addr_abstractcs, fn_mk_abstractcs (dm_cmderr_w1c));
|
||||
// Perform the read
|
||||
dm.write (dm_addr_command,
|
||||
fn_mk_command_access_reg (DM_COMMAND_ACCESS_REG_SIZE_LOWER32,
|
||||
False, // postexec
|
||||
True, // transfer
|
||||
False, // write
|
||||
regno));
|
||||
// Read status to check no error
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
while (fn_abstractcs_busy (rg_abstractcs)) seq
|
||||
$display ("Testbench: read reg: busy");
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
endseq
|
||||
if (fn_abstractcs_cmderr (rg_abstractcs) != DM_ABSTRACTCS_CMDERR_NONE)
|
||||
$display ("Testbench: read reg => ", fshow (fn_abstractcs_cmderr (rg_abstractcs)));
|
||||
else action
|
||||
let x <- dm.av_read (dm_addr_data0);
|
||||
$display ("Testbench: read reg => 0x%08h", x);
|
||||
endaction
|
||||
endseq;
|
||||
endfunction
|
||||
|
||||
@@ -149,31 +149,31 @@ module mkTestbench (Empty);
|
||||
function Stmt fn_stmt_write_reg (Bit #(16) regno, Bit #(32) data);
|
||||
return
|
||||
seq
|
||||
$display ("----------------\nWrite RISC-V reg");
|
||||
// Clear any prior error status
|
||||
dm.write (dm_addr_abstractcs, fn_mk_abstractcs (dm_cmderr_w1c));
|
||||
// Write data0
|
||||
dm.write (dm_addr_data0, data);
|
||||
// Perform the write
|
||||
dm.write (dm_addr_command,
|
||||
fn_mk_command_access_reg (DM_COMMAND_ACCESS_REG_SIZE_LOWER32,
|
||||
False, // postexec
|
||||
True, // transfer
|
||||
True, // write
|
||||
regno));
|
||||
// Read status to check no error
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
while (fn_abstractcs_busy (rg_abstractcs)) seq
|
||||
$display ("Testbench: write reg: busy");
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
endseq
|
||||
$display ("Testbench: write reg => ", fshow (fn_abstractcs_cmderr (rg_abstractcs)));
|
||||
$display ("----------------\nWrite RISC-V reg");
|
||||
// Clear any prior error status
|
||||
dm.write (dm_addr_abstractcs, fn_mk_abstractcs (dm_cmderr_w1c));
|
||||
// Write data0
|
||||
dm.write (dm_addr_data0, data);
|
||||
// Perform the write
|
||||
dm.write (dm_addr_command,
|
||||
fn_mk_command_access_reg (DM_COMMAND_ACCESS_REG_SIZE_LOWER32,
|
||||
False, // postexec
|
||||
True, // transfer
|
||||
True, // write
|
||||
regno));
|
||||
// Read status to check no error
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
while (fn_abstractcs_busy (rg_abstractcs)) seq
|
||||
$display ("Testbench: write reg: busy");
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
endseq
|
||||
$display ("Testbench: write reg => ", fshow (fn_abstractcs_cmderr (rg_abstractcs)));
|
||||
endseq;
|
||||
endfunction
|
||||
|
||||
@@ -188,102 +188,102 @@ module mkTestbench (Empty);
|
||||
|
||||
Stmt stmt_wait_for_sb_nonbusy = (
|
||||
seq
|
||||
rg_busy <= True;
|
||||
while (rg_busy) seq
|
||||
delay (1);
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbcs);
|
||||
let sberror = fn_sbcs_sberror (x);
|
||||
rg_busy <= (sberror == DM_SBERROR_BUSY_STALE);
|
||||
if ( (sberror != DM_SBERROR_NONE)
|
||||
&& (sberror != DM_SBERROR_BUSY_STALE))
|
||||
begin
|
||||
$display ("Testbench: stmt_wait_for_sb_nonbusy: ", fshow (sberror));
|
||||
$finish (1);
|
||||
end
|
||||
endaction
|
||||
endseq
|
||||
rg_busy <= True;
|
||||
while (rg_busy) seq
|
||||
delay (1);
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbcs);
|
||||
let sberror = fn_sbcs_sberror (x);
|
||||
rg_busy <= (sberror == DM_SBERROR_BUSY_STALE);
|
||||
if ( (sberror != DM_SBERROR_NONE)
|
||||
&& (sberror != DM_SBERROR_BUSY_STALE))
|
||||
begin
|
||||
$display ("Testbench: stmt_wait_for_sb_nonbusy: ", fshow (sberror));
|
||||
$finish (1);
|
||||
end
|
||||
endaction
|
||||
endseq
|
||||
endseq);
|
||||
|
||||
// Do a single-read from memory
|
||||
Stmt stmt_mem_read_1 = (
|
||||
seq
|
||||
dm.write (dm_addr_sbaddress0, 'h1_0000);
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (True, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
False, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbdata0);
|
||||
$display ("stmt_mem_read_1: read-data = 0x%08h", x);
|
||||
endaction
|
||||
dm.write (dm_addr_sbaddress0, 'h1_0000);
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (True, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
False, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbdata0);
|
||||
$display ("stmt_mem_read_1: read-data = 0x%08h", x);
|
||||
endaction
|
||||
endseq);
|
||||
|
||||
// Do a multiple-read from memory
|
||||
Stmt stmt_mem_read_4 = (
|
||||
seq
|
||||
dm.write (dm_addr_sbaddress0, 'h1_0000);
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (True, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
True, // sbautoincrement
|
||||
True, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
for (rg_j <= 0; rg_j < 3; rg_j <= rg_j + 1) seq
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbdata0);
|
||||
$display ("stmt_mem_read_4: read-data [%0d] = 0x%08h", rg_j, x);
|
||||
endaction
|
||||
endseq
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (False, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
False, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbdata0);
|
||||
$display ("stmt_mem_read_4: read-data [%0d] = 0x%08h", rg_j, x);
|
||||
endaction
|
||||
dm.write (dm_addr_sbaddress0, 'h1_0000);
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (True, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
True, // sbautoincrement
|
||||
True, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
for (rg_j <= 0; rg_j < 3; rg_j <= rg_j + 1) seq
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbdata0);
|
||||
$display ("stmt_mem_read_4: read-data [%0d] = 0x%08h", rg_j, x);
|
||||
endaction
|
||||
endseq
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (False, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
False, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbdata0);
|
||||
$display ("stmt_mem_read_4: read-data [%0d] = 0x%08h", rg_j, x);
|
||||
endaction
|
||||
endseq);
|
||||
|
||||
// Do a single-write to memory
|
||||
Stmt stmt_mem_write_1 = (
|
||||
seq
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (False, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
False, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
dm.write (dm_addr_sbaddress0, 'h1_0000);
|
||||
dm.write (dm_addr_sbdata0, 'h_BEEF);
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (False, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
False, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
dm.write (dm_addr_sbaddress0, 'h1_0000);
|
||||
dm.write (dm_addr_sbdata0, 'h_BEEF);
|
||||
endseq);
|
||||
|
||||
// Do a multiple-write to memory
|
||||
Stmt stmt_mem_write_4 = (
|
||||
seq
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (False, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
True, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
rg_addr <= 'h_2000;
|
||||
rg_data <= 'h_DAFA_0000;
|
||||
endaction
|
||||
dm.write (dm_addr_sbaddress0, rg_addr);
|
||||
for (rg_j <= 0; rg_j < 4; rg_j <= rg_j + 1) seq
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
$display ("stmt_mem_write_4: [0x%08h] x = 0x%08h", rg_addr + rg_j, rg_data);
|
||||
dm.write (dm_addr_sbdata0, rg_data);
|
||||
rg_data <= rg_data + 1;
|
||||
endaction
|
||||
endseq
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (False, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
True, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
rg_addr <= 'h_2000;
|
||||
rg_data <= 'h_DAFA_0000;
|
||||
endaction
|
||||
dm.write (dm_addr_sbaddress0, rg_addr);
|
||||
for (rg_j <= 0; rg_j < 4; rg_j <= rg_j + 1) seq
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
$display ("stmt_mem_write_4: [0x%08h] x = 0x%08h", rg_addr + rg_j, rg_data);
|
||||
dm.write (dm_addr_sbdata0, rg_data);
|
||||
rg_data <= rg_data + 1;
|
||||
endaction
|
||||
endseq
|
||||
endseq);
|
||||
|
||||
// ================================================================
|
||||
@@ -291,173 +291,173 @@ module mkTestbench (Empty);
|
||||
|
||||
let dmcontrol_dm_reset
|
||||
= fn_mk_dmcontrol (False, // haltreq
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel
|
||||
0, // hartsel,
|
||||
False, // ndmreset
|
||||
False); // dmactive; assert reset
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel
|
||||
0, // hartsel,
|
||||
False, // ndmreset
|
||||
False); // dmactive; assert reset
|
||||
|
||||
let dmcontrol_ndmreset
|
||||
= fn_mk_dmcontrol (False, // haltreq
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
True, // ndmreset
|
||||
True); // dmactive
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
True, // ndmreset
|
||||
True); // dmactive
|
||||
|
||||
let dmcontrol_err_hasel
|
||||
= fn_mk_dmcontrol (False, // haltreq
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
True, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
True, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
|
||||
let dmcontrol_err_hartsel
|
||||
= fn_mk_dmcontrol (False, // haltreq
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
3, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
3, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
|
||||
let dmcontrol_hartreset
|
||||
= fn_mk_dmcontrol (False, // haltreq
|
||||
False, // resumereq
|
||||
True, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
False, // resumereq
|
||||
True, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
|
||||
let dmcontrol_err_haltreq_resumereq
|
||||
= fn_mk_dmcontrol (True, // haltreq
|
||||
True, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
True, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
|
||||
let dmcontrol_haltreq
|
||||
= fn_mk_dmcontrol (True, // haltreq
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
|
||||
let dmcontrol_resumereq
|
||||
= fn_mk_dmcontrol (False, // haltreq
|
||||
True, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
True, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
|
||||
function Stmt fn_stmt_run_control (DM_Word dm_word);
|
||||
return seq
|
||||
dm.write (dm_addr_dmcontrol, dm_word);
|
||||
delay (5);
|
||||
// Check and show status
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_dmstatus);
|
||||
$display (" ", fshow_dmstatus (x));
|
||||
endaction
|
||||
endseq;
|
||||
dm.write (dm_addr_dmcontrol, dm_word);
|
||||
delay (5);
|
||||
// Check and show status
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_dmstatus);
|
||||
$display (" ", fshow_dmstatus (x));
|
||||
endaction
|
||||
endseq;
|
||||
endfunction
|
||||
|
||||
// ----------------
|
||||
// For single-step, set 'step' bit in DCSR, then run
|
||||
|
||||
let dcsr_step = {4'h4, // xdebugver
|
||||
12'b0,
|
||||
1'b0, // ebreakm
|
||||
1'b0,
|
||||
1'b0, // ebreaks
|
||||
1'b0, // ebreaku
|
||||
1'b0, // stepie
|
||||
1'b0, // stepcount
|
||||
1'b0, // steptime
|
||||
3'b0, // cause
|
||||
3'b0,
|
||||
1'b1, // step
|
||||
2'h3};
|
||||
12'b0,
|
||||
1'b0, // ebreakm
|
||||
1'b0,
|
||||
1'b0, // ebreaks
|
||||
1'b0, // ebreaku
|
||||
1'b0, // stepie
|
||||
1'b0, // stepcount
|
||||
1'b0, // steptime
|
||||
3'b0, // cause
|
||||
3'b0,
|
||||
1'b1, // step
|
||||
2'h3};
|
||||
|
||||
Stmt stmt_single_step = (
|
||||
seq
|
||||
// set 'step' in dcsr
|
||||
fn_stmt_write_reg (fromInteger (dm_command_access_reg_regno_csr_0 + csr_addr_dcsr),
|
||||
dcsr_step); // priv
|
||||
fn_stmt_run_control (dmcontrol_resumereq);
|
||||
// set 'step' in dcsr
|
||||
fn_stmt_write_reg (fromInteger (dm_command_access_reg_regno_csr_0 + csr_addr_dcsr),
|
||||
dcsr_step); // priv
|
||||
fn_stmt_run_control (dmcontrol_resumereq);
|
||||
endseq);
|
||||
|
||||
// ================================================================
|
||||
// Top-level test. Comment/Uncomment desired parts.
|
||||
|
||||
Stmt test = seq
|
||||
// Reset DM
|
||||
$display ("----------------\n'Testbench: Reset DM'");
|
||||
fn_stmt_run_control (dmcontrol_dm_reset);
|
||||
// Reset DM
|
||||
$display ("----------------\n'Testbench: Reset DM'");
|
||||
fn_stmt_run_control (dmcontrol_dm_reset);
|
||||
|
||||
/*
|
||||
$display ("----------------\n'Testbench: Reset Platform'");
|
||||
fn_stmt_run_control (dmcontrol_ndmreset);
|
||||
/*
|
||||
$display ("----------------\n'Testbench: Reset Platform'");
|
||||
fn_stmt_run_control (dmcontrol_ndmreset);
|
||||
|
||||
$display ("----------------\n'Testbench: Err hasel'");
|
||||
fn_stmt_run_control (dmcontrol_err_hasel);
|
||||
$display ("----------------\n'Testbench: Err hasel'");
|
||||
fn_stmt_run_control (dmcontrol_err_hasel);
|
||||
|
||||
$display ("----------------\n'Testbench: Err hartsel'");
|
||||
fn_stmt_run_control (dmcontrol_err_hartsel);
|
||||
$display ("----------------\n'Testbench: Err hartsel'");
|
||||
fn_stmt_run_control (dmcontrol_err_hartsel);
|
||||
|
||||
$display ("----------------\n'Testbench: Reset hart'");
|
||||
fn_stmt_run_control (dmcontrol_hartreset);
|
||||
$display ("----------------\n'Testbench: Reset hart'");
|
||||
fn_stmt_run_control (dmcontrol_hartreset);
|
||||
|
||||
$display ("----------------\n'Testbench: Err haltreq and resumereq'");
|
||||
fn_stmt_run_control (dmcontrol_err_haltreq_resumereq);
|
||||
$display ("----------------\n'Testbench: Err haltreq and resumereq'");
|
||||
fn_stmt_run_control (dmcontrol_err_haltreq_resumereq);
|
||||
|
||||
$display ("----------------\n'Testbench: Continue'");
|
||||
fn_stmt_run_control (dmcontrol_resumereq);
|
||||
$display ("----------------\n'Testbench: Continue'");
|
||||
fn_stmt_run_control (dmcontrol_resumereq);
|
||||
|
||||
$display ("----------------\n'Testbench: Halt'");
|
||||
fn_stmt_run_control (dmcontrol_haltreq);
|
||||
$display ("----------------\n'Testbench: Halt'");
|
||||
fn_stmt_run_control (dmcontrol_haltreq);
|
||||
|
||||
$display ("----------------\n'Testbench: Single step'");
|
||||
stmt_single_step;
|
||||
*/
|
||||
$display ("----------------\n'Testbench: Single step'");
|
||||
stmt_single_step;
|
||||
*/
|
||||
|
||||
$display ("----------------\n'Testbench: Read GPR'");
|
||||
fn_stmt_read_reg (fromInteger (dm_command_access_reg_regno_gpr_0 + 5));
|
||||
$display ("----------------\n'Testbench: Read CSR'");
|
||||
fn_stmt_read_reg (fromInteger (dm_command_access_reg_regno_csr_0 + 3));
|
||||
$display ("----------------\n'Testbench: Read GPR'");
|
||||
fn_stmt_read_reg (fromInteger (dm_command_access_reg_regno_gpr_0 + 5));
|
||||
$display ("----------------\n'Testbench: Read CSR'");
|
||||
fn_stmt_read_reg (fromInteger (dm_command_access_reg_regno_csr_0 + 3));
|
||||
|
||||
$display ("----------------\n'Testbench: Write GPR'");
|
||||
fn_stmt_write_reg (fromInteger (dm_command_access_reg_regno_gpr_0 + 5), 'h_AAAA_0005);
|
||||
$display ("----------------\n'Testbench: Write CSR'");
|
||||
fn_stmt_write_reg (fromInteger (dm_command_access_reg_regno_csr_0 + 3), 'h_CCCC_0003);
|
||||
$display ("----------------\n'Testbench: Write GPR'");
|
||||
fn_stmt_write_reg (fromInteger (dm_command_access_reg_regno_gpr_0 + 5), 'h_AAAA_0005);
|
||||
$display ("----------------\n'Testbench: Write CSR'");
|
||||
fn_stmt_write_reg (fromInteger (dm_command_access_reg_regno_csr_0 + 3), 'h_CCCC_0003);
|
||||
|
||||
/*
|
||||
$display ("----------------\n'Testbench: Read 1'");
|
||||
stmt_mem_read_1;
|
||||
/*
|
||||
$display ("----------------\n'Testbench: Read 1'");
|
||||
stmt_mem_read_1;
|
||||
|
||||
$display ("----------------\n'Testbench: Write 1'");
|
||||
stmt_mem_write_1;
|
||||
$display ("----------------\n'Testbench: Write 1'");
|
||||
stmt_mem_write_1;
|
||||
|
||||
$display ("----------------\n'Testbench: Read 4'");
|
||||
stmt_mem_read_4;
|
||||
$display ("----------------\n'Testbench: Read 4'");
|
||||
stmt_mem_read_4;
|
||||
|
||||
$display ("----------------\n'Testbench: Write 4'");
|
||||
stmt_mem_write_4;
|
||||
*/
|
||||
$display ("----------------\n'Testbench: Write 4'");
|
||||
stmt_mem_write_4;
|
||||
*/
|
||||
|
||||
await (False);
|
||||
endseq;
|
||||
await (False);
|
||||
endseq;
|
||||
|
||||
mkAutoFSM (test);
|
||||
|
||||
@@ -518,9 +518,9 @@ module mkHart_Model #(parameter Bit #(10) hart_id) (Hart_DM_IFC);
|
||||
rg_hart_running <= True;
|
||||
|
||||
if (rg_hart_running)
|
||||
$display ("Testbench.hart [%0d].rl_resume_hart: already running", hart_id);
|
||||
$display ("Testbench.hart [%0d].rl_resume_hart: already running", hart_id);
|
||||
else
|
||||
$display ("Testbench.hart [%0d].rl_resume_hart: resuming", hart_id);
|
||||
$display ("Testbench.hart [%0d].rl_resume_hart: resuming", hart_id);
|
||||
|
||||
f_hart_run_rsps.enq (True);
|
||||
endrule
|
||||
@@ -530,9 +530,9 @@ module mkHart_Model #(parameter Bit #(10) hart_id) (Hart_DM_IFC);
|
||||
rg_hart_running <= False;
|
||||
|
||||
if (rg_hart_running)
|
||||
$display ("Testbench.hart [%0d].rl_halt_hart: halting", hart_id);
|
||||
$display ("Testbench.hart [%0d].rl_halt_hart: halting", hart_id);
|
||||
else
|
||||
$display ("Testbench.hart [%0d].rl_halt_hart: already halted", hart_id);
|
||||
$display ("Testbench.hart [%0d].rl_halt_hart: already halted", hart_id);
|
||||
|
||||
f_hart_run_rsps.enq (False);
|
||||
endrule
|
||||
@@ -544,8 +544,8 @@ module mkHart_Model #(parameter Bit #(10) hart_id) (Hart_DM_IFC);
|
||||
let rda <- pop_o (trx_buf_gprs.master.fo_rda);
|
||||
Bit #(32) data = extend (rda.addr) + 'h1000;
|
||||
let rdr = TRX_RdR {trans_id: rda.trans_id,
|
||||
status: TRX_OKAY,
|
||||
data: data};
|
||||
status: TRX_OKAY,
|
||||
data: data};
|
||||
trx_buf_gprs.master.fi_rdr.enq (rdr);
|
||||
$display ("Testbench.hart [%0d]: Read GPR [%0h] => 0x%08h", hart_id, rda.addr, data);
|
||||
endrule
|
||||
@@ -554,8 +554,8 @@ module mkHart_Model #(parameter Bit #(10) hart_id) (Hart_DM_IFC);
|
||||
let rda <- pop_o (trx_buf_csrs.master.fo_rda);
|
||||
Bit #(32) data = extend (rda.addr) + 'h2000;
|
||||
let rdr = TRX_RdR {trans_id: rda.trans_id,
|
||||
status: TRX_OKAY,
|
||||
data: data};
|
||||
status: TRX_OKAY,
|
||||
data: data};
|
||||
trx_buf_csrs.master.fi_rdr.enq (rdr);
|
||||
$display ("Testbench.hart [%0d]: Read CSR [%0h] => 0x%08h", hart_id, rda.addr, data);
|
||||
endrule
|
||||
|
||||
Reference in New Issue
Block a user