PLIC: Restore upstream whitespace
This commit is contained in:
@@ -85,8 +85,8 @@ endinterface
|
||||
// PLIC interface
|
||||
|
||||
interface PLIC_IFC #(numeric type t_n_external_sources,
|
||||
numeric type t_n_targets,
|
||||
numeric type t_max_priority);
|
||||
numeric type t_n_targets,
|
||||
numeric type t_max_priority);
|
||||
// Debugging
|
||||
method Action set_verbosity (Bit #(4) verbosity);
|
||||
method Action show_PLIC_state;
|
||||
@@ -113,9 +113,9 @@ endinterface
|
||||
|
||||
module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
provisos (Add #(1, t_n_external_sources, t_n_sources), // source 0 is reserved for 'no source'
|
||||
Add #(_any_0, TLog #(t_n_sources), T_wd_source_id),
|
||||
Add #(_any_1, TLog #(t_n_targets), T_wd_target_id),
|
||||
Log #(TAdd #(t_max_priority, 1), t_wd_priority));
|
||||
Add #(_any_0, TLog #(t_n_sources), T_wd_source_id),
|
||||
Add #(_any_1, TLog #(t_n_targets), T_wd_target_id),
|
||||
Log #(TAdd #(t_max_priority, 1), t_wd_priority));
|
||||
|
||||
// 0 = quiet; 1 = show PLIC transactions; 2 = also show AXI4 transactions
|
||||
Reg #(Bit #(4)) cfg_verbosity <- mkConfigReg (0);
|
||||
@@ -166,7 +166,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
// Interrupt enables from source to target
|
||||
Vector #(t_n_targets,
|
||||
Vector #(t_n_sources, Reg #(Bool))) vvrg_ie <- replicateM (replicateM (mkReg (False)));
|
||||
Vector #(t_n_sources, Reg #(Bool))) vvrg_ie <- replicateM (replicateM (mkReg (False)));
|
||||
|
||||
// ================================================================
|
||||
// Compute outputs for each target (combinational)
|
||||
@@ -179,42 +179,42 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
// Note: source_ids begin at 1, not 0.
|
||||
for (Integer source_id = 1; source_id < n_sources; source_id = source_id + 1)
|
||||
if ( vrg_source_ip [source_id]
|
||||
&& (vrg_source_prio [source_id] > max_prio)
|
||||
&& (vvrg_ie [target_id][source_id])) begin
|
||||
max_id = fromInteger (source_id);
|
||||
max_prio = vrg_source_prio [source_id];
|
||||
end
|
||||
if ( vrg_source_ip [source_id]
|
||||
&& (vrg_source_prio [source_id] > max_prio)
|
||||
&& (vvrg_ie [target_id][source_id])) begin
|
||||
max_id = fromInteger (source_id);
|
||||
max_prio = vrg_source_prio [source_id];
|
||||
end
|
||||
// Assert: if any interrupt is pending (max_id > 0), then prio > 0
|
||||
return tuple2 (max_prio, max_id);
|
||||
endfunction
|
||||
|
||||
function Action fa_show_PLIC_state;
|
||||
action
|
||||
$display ("----------------");
|
||||
$write ("Src IPs :");
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", pack (vrg_source_ip [source_id]));
|
||||
$display ("");
|
||||
$display ("----------------");
|
||||
$write ("Src IPs :");
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", pack (vrg_source_ip [source_id]));
|
||||
$display ("");
|
||||
|
||||
$write ("Src Prios:");
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", vrg_source_prio [source_id]);
|
||||
$display ("");
|
||||
$write ("Src Prios:");
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", vrg_source_prio [source_id]);
|
||||
$display ("");
|
||||
|
||||
$write ("Src busy :");
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", pack (vrg_source_busy [source_id]));
|
||||
$display ("");
|
||||
$write ("Src busy :");
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", pack (vrg_source_busy [source_id]));
|
||||
$display ("");
|
||||
|
||||
for (Integer target_id = 0; target_id < n_targets; target_id = target_id + 1) begin
|
||||
$write ("T %0d IEs :", target_id);
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", vvrg_ie [target_id][source_id]);
|
||||
match { .max_prio, .max_id } = fn_target_max_prio_and_max_id (fromInteger (target_id));
|
||||
$display (" MaxPri %0d, Thresh %0d, MaxId %0d, Svcing %0d",
|
||||
max_prio, vrg_target_threshold [target_id], max_id, vrg_servicing_source [target_id]);
|
||||
end
|
||||
for (Integer target_id = 0; target_id < n_targets; target_id = target_id + 1) begin
|
||||
$write ("T %0d IEs :", target_id);
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", vvrg_ie [target_id][source_id]);
|
||||
match { .max_prio, .max_id } = fn_target_max_prio_and_max_id (fromInteger (target_id));
|
||||
$display (" MaxPri %0d, Thresh %0d, MaxId %0d, Svcing %0d",
|
||||
max_prio, vrg_target_threshold [target_id], max_id, vrg_servicing_source [target_id]);
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -223,25 +223,25 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
rule rl_reset;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_reset", cur_cycle);
|
||||
$display ("%0d: PLIC.rl_reset", cur_cycle);
|
||||
|
||||
let x <- pop (f_reset_reqs);
|
||||
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1) begin
|
||||
vrg_source_ip [source_id] <= False;
|
||||
vrg_source_busy [source_id] <= False;
|
||||
vrg_source_prio [source_id] <= 0;
|
||||
vrg_source_ip [source_id] <= False;
|
||||
vrg_source_busy [source_id] <= False;
|
||||
vrg_source_prio [source_id] <= 0;
|
||||
end
|
||||
|
||||
for (Integer target_id = 0; target_id < n_targets; target_id = target_id + 1) begin
|
||||
// Mask all interrupts with highest threshold
|
||||
vrg_target_threshold [target_id] <= '1;
|
||||
vrg_servicing_source [target_id] <= 0;
|
||||
// Mask all interrupts with highest threshold
|
||||
vrg_target_threshold [target_id] <= '1;
|
||||
vrg_servicing_source [target_id] <= 0;
|
||||
end
|
||||
|
||||
for (Integer target_id = 0; target_id < n_targets; target_id = target_id + 1)
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
vvrg_ie [target_id][source_id] <= False;
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
vvrg_ie [target_id][source_id] <= False;
|
||||
|
||||
slavePortShim.clear;
|
||||
|
||||
@@ -260,8 +260,8 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
let rda <- get(slavePortShim.master.ar);
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: PLIC.rl_process_rd_req:", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
$display ("%0d: PLIC.rl_process_rd_req:", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
end
|
||||
|
||||
let addr_offset = rda.araddr - rg_addr_base;
|
||||
@@ -269,134 +269,134 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
AXI4_Resp rresp = OKAY;
|
||||
|
||||
if (rda.araddr < rg_addr_base) begin
|
||||
// Technically this should not happen: the fabric should
|
||||
// never have delivered such an addr to this IP.
|
||||
$display ("%0d: ERROR: PLIC.rl_process_rd_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
rresp = DECERR;
|
||||
// Technically this should not happen: the fabric should
|
||||
// never have delivered such an addr to this IP.
|
||||
$display ("%0d: ERROR: PLIC.rl_process_rd_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
rresp = DECERR;
|
||||
end
|
||||
|
||||
// Source Priority
|
||||
else if (addr_offset < 'h1000) begin
|
||||
Bit #(T_wd_source_id) source_id = truncate (addr_offset [11:2]);
|
||||
if ((0 < source_id) && (source_id <= fromInteger (n_sources - 1))) begin
|
||||
rdata = changeWidth (vrg_source_prio [source_id]);
|
||||
Bit #(T_wd_source_id) source_id = truncate (addr_offset [11:2]);
|
||||
if ((0 < source_id) && (source_id <= fromInteger (n_sources - 1))) begin
|
||||
rdata = changeWidth (vrg_source_prio [source_id]);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Source Priority: source %0d = 0x%0h",
|
||||
cur_cycle, source_id, rdata);
|
||||
end
|
||||
else
|
||||
rresp = SLVERR;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Source Priority: source %0d = 0x%0h",
|
||||
cur_cycle, source_id, rdata);
|
||||
end
|
||||
else
|
||||
rresp = SLVERR;
|
||||
end
|
||||
|
||||
// Source IPs (interrupt pending).
|
||||
// Return 32 consecutive IP bits starting with addr.
|
||||
else if (('h1000 <= addr_offset) && (addr_offset < 'h2000)) begin
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [11:0], 5'h0 });
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [11:0], 5'h0 });
|
||||
|
||||
function Bool fn_ip_source_id (Integer source_id_offset);
|
||||
let source_id = source_id_base + fromInteger (source_id_offset);
|
||||
Bool ip_source_id = ( (source_id <= fromInteger (n_sources - 1))
|
||||
? vrg_source_ip [source_id]
|
||||
: False);
|
||||
return ip_source_id;
|
||||
endfunction
|
||||
function Bool fn_ip_source_id (Integer source_id_offset);
|
||||
let source_id = source_id_base + fromInteger (source_id_offset);
|
||||
Bool ip_source_id = ( (source_id <= fromInteger (n_sources - 1))
|
||||
? vrg_source_ip [source_id]
|
||||
: False);
|
||||
return ip_source_id;
|
||||
endfunction
|
||||
|
||||
if (source_id_base <= fromInteger (n_sources - 1)) begin
|
||||
Bit #(32) v_ip = pack (genWith (fn_ip_source_id));
|
||||
rdata = changeWidth (v_ip);
|
||||
if (source_id_base <= fromInteger (n_sources - 1)) begin
|
||||
Bit #(32) v_ip = pack (genWith (fn_ip_source_id));
|
||||
rdata = changeWidth (v_ip);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Intr Pending 32 bits from source %0d = 0x%0h",
|
||||
cur_cycle, source_id_base, rdata);
|
||||
end
|
||||
else
|
||||
rresp = SLVERR;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Intr Pending 32 bits from source %0d = 0x%0h",
|
||||
cur_cycle, source_id_base, rdata);
|
||||
end
|
||||
else
|
||||
rresp = SLVERR;
|
||||
end
|
||||
|
||||
// Source IEs (interrupt enables) for a target
|
||||
// Return 32 consecutive IE bits starting with addr.
|
||||
// Target 0 addrs: 2000-207F, Target 1 addrs: 2080-20FF, ...
|
||||
else if (('h2000 <= addr_offset) && (addr_offset < 'h3000)) begin
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [11:7]);
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [6:0], 5'h0 });
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [11:7]);
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [6:0], 5'h0 });
|
||||
|
||||
function Bool fn_ie_source_id (Integer source_id_offset);
|
||||
let source_id = fromInteger (source_id_offset) + source_id_base;
|
||||
return ( (source_id <= fromInteger (n_sources - 1))
|
||||
? vvrg_ie [target_id][source_id]
|
||||
: False);
|
||||
endfunction
|
||||
function Bool fn_ie_source_id (Integer source_id_offset);
|
||||
let source_id = fromInteger (source_id_offset) + source_id_base;
|
||||
return ( (source_id <= fromInteger (n_sources - 1))
|
||||
? vvrg_ie [target_id][source_id]
|
||||
: False);
|
||||
endfunction
|
||||
|
||||
if ( (source_id_base <= fromInteger (n_sources - 1))
|
||||
&& (target_id <= fromInteger (n_targets - 1))) begin
|
||||
Bit #(32) v_ie = pack (genWith (fn_ie_source_id));
|
||||
rdata = changeWidth (v_ie);
|
||||
if ( (source_id_base <= fromInteger (n_sources - 1))
|
||||
&& (target_id <= fromInteger (n_targets - 1))) begin
|
||||
Bit #(32) v_ie = pack (genWith (fn_ie_source_id));
|
||||
rdata = changeWidth (v_ie);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Intr Enable 32 bits from source %0d = 0x%0h",
|
||||
cur_cycle, source_id_base, rdata);
|
||||
end
|
||||
else
|
||||
rresp = SLVERR;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Intr Enable 32 bits from source %0d = 0x%0h",
|
||||
cur_cycle, source_id_base, rdata);
|
||||
end
|
||||
else
|
||||
rresp = SLVERR;
|
||||
end
|
||||
|
||||
// Target threshold
|
||||
else if ((addr_offset [31:0] & 32'hFFFF_0FFF) == 32'h0020_0000) begin
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
rdata = changeWidth (vrg_target_threshold [target_id]);
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
rdata = changeWidth (vrg_target_threshold [target_id]);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Threshold for target %0d = 0x%0h",
|
||||
cur_cycle, target_id, rdata);
|
||||
end
|
||||
else
|
||||
rresp = SLVERR;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Threshold for target %0d = 0x%0h",
|
||||
cur_cycle, target_id, rdata);
|
||||
end
|
||||
else
|
||||
rresp = SLVERR;
|
||||
end
|
||||
|
||||
// Interrupt service claim by target
|
||||
else if ((addr_offset [31:0] & 32'hFFFF_0FFF) == 32'h0020_0004) begin
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
match { .max_prio, .max_id } = fn_target_max_prio_and_max_id (target_id);
|
||||
Bool eip = (max_prio > vrg_target_threshold [target_id]);
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
if (vrg_servicing_source [target_id] != 0) begin
|
||||
$display ("%0d: ERROR: PLIC: target %0d claiming without prior completion",
|
||||
cur_cycle, target_id);
|
||||
$display (" Still servicing interrupt from source %0d", vrg_servicing_source [target_id]);
|
||||
$display (" Trying to claim service for source %0d", max_id);
|
||||
$display (" Ignoring.");
|
||||
rresp = SLVERR;
|
||||
end
|
||||
else begin
|
||||
if (max_id != 0) begin
|
||||
vrg_source_ip [max_id] <= False;
|
||||
vrg_source_busy [max_id] <= True;
|
||||
vrg_servicing_source [target_id] <= truncate (max_id);
|
||||
rdata = changeWidth (max_id);
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
match { .max_prio, .max_id } = fn_target_max_prio_and_max_id (target_id);
|
||||
Bool eip = (max_prio > vrg_target_threshold [target_id]);
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
if (vrg_servicing_source [target_id] != 0) begin
|
||||
$display ("%0d: ERROR: PLIC: target %0d claiming without prior completion",
|
||||
cur_cycle, target_id);
|
||||
$display (" Still servicing interrupt from source %0d", vrg_servicing_source [target_id]);
|
||||
$display (" Trying to claim service for source %0d", max_id);
|
||||
$display (" Ignoring.");
|
||||
rresp = SLVERR;
|
||||
end
|
||||
else begin
|
||||
if (max_id != 0) begin
|
||||
vrg_source_ip [max_id] <= False;
|
||||
vrg_source_busy [max_id] <= True;
|
||||
vrg_servicing_source [target_id] <= truncate (max_id);
|
||||
rdata = changeWidth (max_id);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Claim for target %0d = 0x%0h",
|
||||
cur_cycle, target_id, rdata);
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
rresp = SLVERR;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Claim for target %0d = 0x%0h",
|
||||
cur_cycle, target_id, rdata);
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
rresp = SLVERR;
|
||||
end
|
||||
|
||||
else
|
||||
rresp = SLVERR;
|
||||
rresp = SLVERR;
|
||||
|
||||
if (rresp != OKAY) begin
|
||||
$display ("%0d: ERROR: PLIC.rl_process_rd_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
$display ("%0d: ERROR: PLIC.rl_process_rd_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
end
|
||||
|
||||
if ((valueOf (Wd_Data) == 64) && ((addr_offset & 'h7) == 'h4))
|
||||
rdata = { rdata [31:0], 32'h0 };
|
||||
rdata = { rdata [31:0], 32'h0 };
|
||||
|
||||
// Send read-response to bus
|
||||
Fabric_Data x = truncate (rdata);
|
||||
@@ -408,9 +408,9 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
slavePortShim.master.r.put(rdr);
|
||||
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: PLIC.rl_process_rd_req", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
$display (" ", fshow (rdr));
|
||||
$display ("%0d: PLIC.rl_process_rd_req", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
$display (" ", fshow (rdr));
|
||||
end
|
||||
endrule: rl_process_rd_req
|
||||
|
||||
@@ -424,126 +424,126 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
let wra <- get(slavePortShim.master.aw);
|
||||
let wrd <- get(slavePortShim.master.w);
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: PLIC.rl_process_wr_req", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
$display ("%0d: PLIC.rl_process_wr_req", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
end
|
||||
|
||||
let addr_offset = wra.awaddr - rg_addr_base;
|
||||
let wdata32 = (((valueOf (Wd_Data) == 64) && ((addr_offset & 'h7) == 'h4))
|
||||
? wrd.wdata [63:32]
|
||||
: wrd.wdata [31:0]);
|
||||
? wrd.wdata [63:32]
|
||||
: wrd.wdata [31:0]);
|
||||
let bresp = OKAY;
|
||||
|
||||
if (wra.awaddr < rg_addr_base) begin
|
||||
// Technically this should not happen: the fabric should
|
||||
// never have delivered such an addr to this IP.
|
||||
$display ("%0d: ERROR: PLIC.rl_process_wr_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
bresp = DECERR;
|
||||
// Technically this should not happen: the fabric should
|
||||
// never have delivered such an addr to this IP.
|
||||
$display ("%0d: ERROR: PLIC.rl_process_wr_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
bresp = DECERR;
|
||||
end
|
||||
|
||||
// Source priority
|
||||
else if (addr_offset < 'h1000) begin
|
||||
Bit #(T_wd_source_id) source_id = truncate (addr_offset [11:2]);
|
||||
if ((0 < source_id) && (source_id <= fromInteger (n_sources - 1))) begin
|
||||
vrg_source_prio [source_id] <= changeWidth (wdata32);
|
||||
Bit #(T_wd_source_id) source_id = truncate (addr_offset [11:2]);
|
||||
if ((0 < source_id) && (source_id <= fromInteger (n_sources - 1))) begin
|
||||
vrg_source_prio [source_id] <= changeWidth (wdata32);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing Source Priority: source %0d = 0x%0h",
|
||||
cur_cycle, source_id, wdata32);
|
||||
end
|
||||
else begin
|
||||
// Note: write to source_id 0 is error; should it just be ignored?
|
||||
bresp = SLVERR;
|
||||
end
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing Source Priority: source %0d = 0x%0h",
|
||||
cur_cycle, source_id, wdata32);
|
||||
end
|
||||
else begin
|
||||
// Note: write to source_id 0 is error; should it just be ignored?
|
||||
bresp = SLVERR;
|
||||
end
|
||||
end
|
||||
|
||||
// Source IPs (interrupt pending).
|
||||
// Read-only, so ignore write; just check that addr ok.
|
||||
else if (('h1000 <= addr_offset) && (addr_offset < 'h2000)) begin
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [11:0], 5'h0 });
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [11:0], 5'h0 });
|
||||
|
||||
if (source_id_base <= fromInteger (n_sources - 1)) begin
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: Ignoring write to Read-only Intr Pending 32 bits from source %0d",
|
||||
cur_cycle, source_id_base);
|
||||
end
|
||||
else
|
||||
bresp = SLVERR;
|
||||
if (source_id_base <= fromInteger (n_sources - 1)) begin
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: Ignoring write to Read-only Intr Pending 32 bits from source %0d",
|
||||
cur_cycle, source_id_base);
|
||||
end
|
||||
else
|
||||
bresp = SLVERR;
|
||||
end
|
||||
|
||||
// Source IEs (interrupt enables) for a target
|
||||
// Write 32 consecutive IE bits starting with addr.
|
||||
// Target 0 addrs: 2000-207F, Target 1 addrs: 2080-20FF, ...
|
||||
else if (('h2000 <= addr_offset) && (addr_offset < 'h3000)) begin
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [11:7]);
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [6:0], 5'h0 });
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [11:7]);
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [6:0], 5'h0 });
|
||||
|
||||
if ( (source_id_base <= fromInteger (n_sources - 1))
|
||||
&& (target_id <= fromInteger (n_targets - 1))) begin
|
||||
for (Bit #(T_wd_source_id) k = 0; k < 32; k = k + 1) begin
|
||||
Bit #(T_wd_source_id) source_id = source_id_base + k;
|
||||
if (source_id <= fromInteger (n_sources - 1))
|
||||
vvrg_ie [target_id][source_id] <= unpack (wdata32 [k]);
|
||||
end
|
||||
if ( (source_id_base <= fromInteger (n_sources - 1))
|
||||
&& (target_id <= fromInteger (n_targets - 1))) begin
|
||||
for (Bit #(T_wd_source_id) k = 0; k < 32; k = k + 1) begin
|
||||
Bit #(T_wd_source_id) source_id = source_id_base + k;
|
||||
if (source_id <= fromInteger (n_sources - 1))
|
||||
vvrg_ie [target_id][source_id] <= unpack (wdata32 [k]);
|
||||
end
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing Intr Enable 32 bits for target %0d from source %0d = 0x%0h",
|
||||
cur_cycle, target_id, source_id_base, wdata32);
|
||||
end
|
||||
else
|
||||
bresp = SLVERR;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing Intr Enable 32 bits for target %0d from source %0d = 0x%0h",
|
||||
cur_cycle, target_id, source_id_base, wdata32);
|
||||
end
|
||||
else
|
||||
bresp = SLVERR;
|
||||
end
|
||||
|
||||
// Target threshold
|
||||
else if ((addr_offset [31:0] & 32'hFFFF_0FFF) == 32'h0020_0000) begin
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
vrg_target_threshold [target_id] <= changeWidth (wdata32);
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
vrg_target_threshold [target_id] <= changeWidth (wdata32);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing threshold for target %0d = 0x%0h",
|
||||
cur_cycle, target_id, wdata32);
|
||||
end
|
||||
else
|
||||
bresp = SLVERR;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing threshold for target %0d = 0x%0h",
|
||||
cur_cycle, target_id, wdata32);
|
||||
end
|
||||
else
|
||||
bresp = SLVERR;
|
||||
end
|
||||
|
||||
// Interrupt service completion by target
|
||||
// Actual memory-write-data is irrelevant.
|
||||
else if ((addr_offset [31:0] & 32'hFFFF_0FFF) == 32'h0020_0004) begin
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
Bit #(T_wd_source_id) source_id = zeroExtend (vrg_servicing_source [target_id]);
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
Bit #(T_wd_source_id) source_id = zeroExtend (vrg_servicing_source [target_id]);
|
||||
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
if (vrg_source_busy [source_id]) begin
|
||||
vrg_source_busy [source_id] <= False;
|
||||
vrg_servicing_source [target_id] <= 0;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing completion for target %0d for source 0x%0h",
|
||||
cur_cycle, target_id, source_id);
|
||||
end
|
||||
else begin
|
||||
$display ("%0d: ERROR: PLIC: interrupt completion to source that is not being serviced",
|
||||
cur_cycle);
|
||||
$display (" Completion message from target %0d to source %0d", target_id, source_id);
|
||||
$display (" Ignoring");
|
||||
bresp = SLVERR;
|
||||
end
|
||||
end
|
||||
else
|
||||
bresp = SLVERR;
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
if (vrg_source_busy [source_id]) begin
|
||||
vrg_source_busy [source_id] <= False;
|
||||
vrg_servicing_source [target_id] <= 0;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing completion for target %0d for source 0x%0h",
|
||||
cur_cycle, target_id, source_id);
|
||||
end
|
||||
else begin
|
||||
$display ("%0d: ERROR: PLIC: interrupt completion to source that is not being serviced",
|
||||
cur_cycle);
|
||||
$display (" Completion message from target %0d to source %0d", target_id, source_id);
|
||||
$display (" Ignoring");
|
||||
bresp = SLVERR;
|
||||
end
|
||||
end
|
||||
else
|
||||
bresp = SLVERR;
|
||||
end
|
||||
|
||||
else
|
||||
bresp = SLVERR;
|
||||
bresp = SLVERR;
|
||||
|
||||
if (bresp != OKAY) begin
|
||||
$display ("%0d: ERROR: PLIC.rl_process_wr_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
$display ("%0d: ERROR: PLIC.rl_process_wr_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
end
|
||||
|
||||
// Send write-response to bus
|
||||
@@ -553,10 +553,10 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
slavePortShim.master.b.put(wrr);
|
||||
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: PLIC.AXI4.rl_process_wr_req", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
$display (" ", fshow (wrr));
|
||||
$display ("%0d: PLIC.AXI4.rl_process_wr_req", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
$display (" ", fshow (wrr));
|
||||
end
|
||||
endrule: rl_process_wr_req
|
||||
|
||||
@@ -565,18 +565,18 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
function PLIC_Source_IFC fn_mk_PLIC_Source_IFC (Integer source_id);
|
||||
return interface PLIC_Source_IFC;
|
||||
method Action m_interrupt_req (Bool set_not_clear);
|
||||
action
|
||||
if (! vrg_source_busy [source_id + 1]) begin
|
||||
vrg_source_ip [source_id + 1] <= set_not_clear;
|
||||
method Action m_interrupt_req (Bool set_not_clear);
|
||||
action
|
||||
if (! vrg_source_busy [source_id + 1]) begin
|
||||
vrg_source_ip [source_id + 1] <= set_not_clear;
|
||||
|
||||
if ((cfg_verbosity > 0) && (vrg_source_ip [source_id + 1] != set_not_clear))
|
||||
$display ("%0d: %m.m_interrupt_req: changing vrg_source_ip [%0d] to %0d",
|
||||
cur_cycle, source_id + 1, pack (set_not_clear));
|
||||
end
|
||||
endaction
|
||||
endmethod
|
||||
endinterface;
|
||||
if ((cfg_verbosity > 0) && (vrg_source_ip [source_id + 1] != set_not_clear))
|
||||
$display ("%0d: %m.m_interrupt_req: changing vrg_source_ip [%0d] to %0d",
|
||||
cur_cycle, source_id + 1, pack (set_not_clear));
|
||||
end
|
||||
endaction
|
||||
endmethod
|
||||
endinterface;
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -584,12 +584,12 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
function PLIC_Target_IFC fn_mk_PLIC_Target_IFC (Integer target_id);
|
||||
return interface PLIC_Target_IFC;
|
||||
method Bool m_eip; // external interrupt pending
|
||||
match { .max_prio, .max_id } = fn_target_max_prio_and_max_id (fromInteger (target_id));
|
||||
Bool eip = (max_prio > vrg_target_threshold [target_id]);
|
||||
return eip;
|
||||
endmethod
|
||||
endinterface;
|
||||
method Bool m_eip; // external interrupt pending
|
||||
match { .max_prio, .max_id } = fn_target_max_prio_and_max_id (fromInteger (target_id));
|
||||
Bool eip = (max_prio > vrg_target_threshold [target_id]);
|
||||
return eip;
|
||||
endmethod
|
||||
endinterface;
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -610,18 +610,18 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
// set_addr_map should be called after this module's reset
|
||||
method Action set_addr_map (Bit #(64) addr_base, Bit #(64) addr_lim);
|
||||
if (addr_base [1:0] != 0)
|
||||
$display ("%0d: WARNING: PLIC.set_addr_map: addr_base 0x%0h is not 4-Byte-aligned",
|
||||
cur_cycle, addr_base);
|
||||
$display ("%0d: WARNING: PLIC.set_addr_map: addr_base 0x%0h is not 4-Byte-aligned",
|
||||
cur_cycle, addr_base);
|
||||
|
||||
if (addr_lim [1:0] != 0)
|
||||
$display ("%0d: WARNING: PLIC.set_addr_map: addr_lim 0x%0h is not 4-Byte-aligned",
|
||||
cur_cycle, addr_lim);
|
||||
$display ("%0d: WARNING: PLIC.set_addr_map: addr_lim 0x%0h is not 4-Byte-aligned",
|
||||
cur_cycle, addr_lim);
|
||||
|
||||
rg_addr_base <= addr_base;
|
||||
rg_addr_lim <= addr_lim;
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.set_addr_map: base 0x%0h limit 0x%0h", cur_cycle, addr_base, addr_lim);
|
||||
$display ("%0d: PLIC.set_addr_map: base 0x%0h limit 0x%0h", cur_cycle, addr_base, addr_lim);
|
||||
endmethod
|
||||
|
||||
// Memory-mapped access
|
||||
|
||||
Reference in New Issue
Block a user