Fixes for synthesis

This commit is contained in:
Peter Rugg
2020-06-05 17:40:28 +01:00
parent 046319b909
commit 962ade1092
16 changed files with 1534 additions and 1406 deletions

View File

@@ -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

View File

@@ -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;
// ================================================================

View File

@@ -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

View File

@@ -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
// ================================================================

View File

@@ -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

View File

@@ -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