diff --git a/src_Core/PLIC/PLIC.bsv b/src_Core/PLIC/PLIC.bsv index 32d9465..18e7a5b 100644 --- a/src_Core/PLIC/PLIC.bsv +++ b/src_Core/PLIC/PLIC.bsv @@ -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