diff --git a/hw/ip_templates/rv_plic/README.md b/hw/ip_templates/rv_plic/README.md index 254925c96d1ba..71e58aad8da77 100644 --- a/hw/ip_templates/rv_plic/README.md +++ b/hw/ip_templates/rv_plic/README.md @@ -21,6 +21,9 @@ The RV_PLIC module is designed to manage various interrupt sources from the peripherals. It receives interrupt events as either edge or level of the incoming interrupt signals (``intr_src_i``) and can notify multiple targets. +Note that the lowest bit of ``intr_src_i`` is must be tied to 0 because it corresponds interrupt ID 0 which is reserved to mean "no interrupt". This is +verified with an assertion inside `rv_plic`. + ## Compatibility The RV_PLIC is compatible with any RISC-V core implementing the RISC-V privilege specification. diff --git a/hw/ip_templates/rv_plic/data/rv_plic.hjson.tpl b/hw/ip_templates/rv_plic/data/rv_plic.hjson.tpl index 689366432e02f..729b90602ca60 100644 --- a/hw/ip_templates/rv_plic/data/rv_plic.hjson.tpl +++ b/hw/ip_templates/rv_plic/data/rv_plic.hjson.tpl @@ -54,7 +54,7 @@ param_list: [ { name: "NumSrc", - desc: "Number of interrupt sources", + desc: "Number of interrupt sources (including the 'no interrupt' ID 0)", type: "int", default: "${src}", local: "true" diff --git a/hw/ip_templates/rv_plic/fpv/tb/rv_plic_tb.sv.tpl b/hw/ip_templates/rv_plic/fpv/tb/rv_plic_tb.sv.tpl index a61d34f8106c0..59de6c43bfeea 100644 --- a/hw/ip_templates/rv_plic/fpv/tb/rv_plic_tb.sv.tpl +++ b/hw/ip_templates/rv_plic/fpv/tb/rv_plic_tb.sv.tpl @@ -12,7 +12,7 @@ module ${module_instance_name}_tb import ${module_instance_name}_reg_pkg::*; #( input rst_ni, input tlul_pkg::tl_h2d_t [NumInstances-1:0] tl_i, output tlul_pkg::tl_d2h_t [NumInstances-1:0] tl_o, - input [NumInstances-1:0][NumSrc-1:0] intr_src_i, + input [NumInstances-1:0][NumSrc-2:0] intr_src_nonzero_i, input prim_alert_pkg::alert_rx_t [NumInstances-1:0][NumAlerts-1:0] alert_rx_i, output prim_alert_pkg::alert_tx_t [NumInstances-1:0][NumAlerts-1:0] alert_tx_o, output [NumInstances-1:0][NumTarget-1:0] irq_o, @@ -29,7 +29,8 @@ module ${module_instance_name}_tb import ${module_instance_name}_reg_pkg::*; #( .rst_ni , .tl_i (tl_i[0]), .tl_o (tl_o[0]), - .intr_src_i (intr_src_i[0]), + // Interrupt 0 must be tied to 0. + .intr_src_i ({intr_src_nonzero_i[0], 1'b0}), .alert_rx_i (alert_rx_i[0]), .alert_tx_o (alert_tx_o[0]), .irq_o (irq_o[0]), diff --git a/hw/ip_templates/rv_plic/rtl/rv_plic.sv.tpl b/hw/ip_templates/rv_plic/rtl/rv_plic.sv.tpl index 0f6b48f76eca7..8c9b8d9292bf1 100644 --- a/hw/ip_templates/rv_plic/rtl/rv_plic.sv.tpl +++ b/hw/ip_templates/rv_plic/rtl/rv_plic.sv.tpl @@ -47,7 +47,9 @@ module ${module_instance_name} import ${module_instance_name}_reg_pkg::*; #( output top_racl_pkg::racl_error_log_t racl_error_o, % endif - // Interrupt Sources + // Interrupt Sources. Note that the lowest bit must be tied to 0 because it + // is reserved for "no interrupt". Because the lowest bit is always 0, + // only NumSrc-1 interrupts are usable. input [NumSrc-1:0] intr_src_i, // Alerts @@ -283,8 +285,8 @@ module ${module_instance_name} import ${module_instance_name}_reg_pkg::*; #( `ASSERT_KNOWN(IrqIdKnownO_A, irq_id_o[k]) end - // Assume - `ASSUME(Irq0Tied_A, intr_src_i[0] == 1'b0) + // Bit 0 must be tied to zero because it is reserved for "no interrupt". + `ASSERT(Irq0Tied_A, intr_src_i[0] == 1'b0) // This assertion should be provable in FPV because we don't have a block-level DV environment. It // is trying to say that any integrity error detected inside the register block (u_reg) will cause diff --git a/hw/top_darjeeling/ip_autogen/rv_plic/README.md b/hw/top_darjeeling/ip_autogen/rv_plic/README.md index 254925c96d1ba..71e58aad8da77 100644 --- a/hw/top_darjeeling/ip_autogen/rv_plic/README.md +++ b/hw/top_darjeeling/ip_autogen/rv_plic/README.md @@ -21,6 +21,9 @@ The RV_PLIC module is designed to manage various interrupt sources from the peripherals. It receives interrupt events as either edge or level of the incoming interrupt signals (``intr_src_i``) and can notify multiple targets. +Note that the lowest bit of ``intr_src_i`` is must be tied to 0 because it corresponds interrupt ID 0 which is reserved to mean "no interrupt". This is +verified with an assertion inside `rv_plic`. + ## Compatibility The RV_PLIC is compatible with any RISC-V core implementing the RISC-V privilege specification. diff --git a/hw/top_darjeeling/ip_autogen/rv_plic/data/rv_plic.hjson b/hw/top_darjeeling/ip_autogen/rv_plic/data/rv_plic.hjson index ef0f9de39ae3f..cb2b6a2edd6b1 100644 --- a/hw/top_darjeeling/ip_autogen/rv_plic/data/rv_plic.hjson +++ b/hw/top_darjeeling/ip_autogen/rv_plic/data/rv_plic.hjson @@ -42,7 +42,7 @@ param_list: [ { name: "NumSrc", - desc: "Number of interrupt sources", + desc: "Number of interrupt sources (including the 'no interrupt' ID 0)", type: "int", default: "132", local: "true" diff --git a/hw/top_darjeeling/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv b/hw/top_darjeeling/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv index 8a64257766d71..38b0e4744dd60 100644 --- a/hw/top_darjeeling/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv +++ b/hw/top_darjeeling/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv @@ -12,7 +12,7 @@ module rv_plic_tb import rv_plic_reg_pkg::*; #( input rst_ni, input tlul_pkg::tl_h2d_t [NumInstances-1:0] tl_i, output tlul_pkg::tl_d2h_t [NumInstances-1:0] tl_o, - input [NumInstances-1:0][NumSrc-1:0] intr_src_i, + input [NumInstances-1:0][NumSrc-2:0] intr_src_nonzero_i, input prim_alert_pkg::alert_rx_t [NumInstances-1:0][NumAlerts-1:0] alert_rx_i, output prim_alert_pkg::alert_tx_t [NumInstances-1:0][NumAlerts-1:0] alert_tx_o, output [NumInstances-1:0][NumTarget-1:0] irq_o, @@ -29,7 +29,8 @@ module rv_plic_tb import rv_plic_reg_pkg::*; #( .rst_ni , .tl_i (tl_i[0]), .tl_o (tl_o[0]), - .intr_src_i (intr_src_i[0]), + // Interrupt 0 must be tied to 0. + .intr_src_i ({intr_src_nonzero_i[0], 1'b0}), .alert_rx_i (alert_rx_i[0]), .alert_tx_o (alert_tx_o[0]), .irq_o (irq_o[0]), diff --git a/hw/top_darjeeling/ip_autogen/rv_plic/rtl/rv_plic.sv b/hw/top_darjeeling/ip_autogen/rv_plic/rtl/rv_plic.sv index fc275c6a95518..3686536649664 100644 --- a/hw/top_darjeeling/ip_autogen/rv_plic/rtl/rv_plic.sv +++ b/hw/top_darjeeling/ip_autogen/rv_plic/rtl/rv_plic.sv @@ -36,7 +36,9 @@ module rv_plic import rv_plic_reg_pkg::*; #( input tlul_pkg::tl_h2d_t tl_i, output tlul_pkg::tl_d2h_t tl_o, - // Interrupt Sources + // Interrupt Sources. Note that the lowest bit must be tied to 0 because it + // is reserved for "no interrupt". Because the lowest bit is always 0, + // only NumSrc-1 interrupts are usable. input [NumSrc-1:0] intr_src_i, // Alerts @@ -376,8 +378,8 @@ module rv_plic import rv_plic_reg_pkg::*; #( `ASSERT_KNOWN(IrqIdKnownO_A, irq_id_o[k]) end - // Assume - `ASSUME(Irq0Tied_A, intr_src_i[0] == 1'b0) + // Bit 0 must be tied to zero because it is reserved for "no interrupt". + `ASSERT(Irq0Tied_A, intr_src_i[0] == 1'b0) // This assertion should be provable in FPV because we don't have a block-level DV environment. It // is trying to say that any integrity error detected inside the register block (u_reg) will cause diff --git a/hw/top_earlgrey/ip_autogen/rv_plic/README.md b/hw/top_earlgrey/ip_autogen/rv_plic/README.md index 254925c96d1ba..71e58aad8da77 100644 --- a/hw/top_earlgrey/ip_autogen/rv_plic/README.md +++ b/hw/top_earlgrey/ip_autogen/rv_plic/README.md @@ -21,6 +21,9 @@ The RV_PLIC module is designed to manage various interrupt sources from the peripherals. It receives interrupt events as either edge or level of the incoming interrupt signals (``intr_src_i``) and can notify multiple targets. +Note that the lowest bit of ``intr_src_i`` is must be tied to 0 because it corresponds interrupt ID 0 which is reserved to mean "no interrupt". This is +verified with an assertion inside `rv_plic`. + ## Compatibility The RV_PLIC is compatible with any RISC-V core implementing the RISC-V privilege specification. diff --git a/hw/top_earlgrey/ip_autogen/rv_plic/data/rv_plic.hjson b/hw/top_earlgrey/ip_autogen/rv_plic/data/rv_plic.hjson index 3f42f115c91ea..e64b4a2a6353c 100644 --- a/hw/top_earlgrey/ip_autogen/rv_plic/data/rv_plic.hjson +++ b/hw/top_earlgrey/ip_autogen/rv_plic/data/rv_plic.hjson @@ -42,7 +42,7 @@ param_list: [ { name: "NumSrc", - desc: "Number of interrupt sources", + desc: "Number of interrupt sources (including the 'no interrupt' ID 0)", type: "int", default: "186", local: "true" diff --git a/hw/top_earlgrey/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv b/hw/top_earlgrey/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv index 8a64257766d71..38b0e4744dd60 100644 --- a/hw/top_earlgrey/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv +++ b/hw/top_earlgrey/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv @@ -12,7 +12,7 @@ module rv_plic_tb import rv_plic_reg_pkg::*; #( input rst_ni, input tlul_pkg::tl_h2d_t [NumInstances-1:0] tl_i, output tlul_pkg::tl_d2h_t [NumInstances-1:0] tl_o, - input [NumInstances-1:0][NumSrc-1:0] intr_src_i, + input [NumInstances-1:0][NumSrc-2:0] intr_src_nonzero_i, input prim_alert_pkg::alert_rx_t [NumInstances-1:0][NumAlerts-1:0] alert_rx_i, output prim_alert_pkg::alert_tx_t [NumInstances-1:0][NumAlerts-1:0] alert_tx_o, output [NumInstances-1:0][NumTarget-1:0] irq_o, @@ -29,7 +29,8 @@ module rv_plic_tb import rv_plic_reg_pkg::*; #( .rst_ni , .tl_i (tl_i[0]), .tl_o (tl_o[0]), - .intr_src_i (intr_src_i[0]), + // Interrupt 0 must be tied to 0. + .intr_src_i ({intr_src_nonzero_i[0], 1'b0}), .alert_rx_i (alert_rx_i[0]), .alert_tx_o (alert_tx_o[0]), .irq_o (irq_o[0]), diff --git a/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic.sv b/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic.sv index e06a6fe31d583..ace45a2c0808b 100644 --- a/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic.sv +++ b/hw/top_earlgrey/ip_autogen/rv_plic/rtl/rv_plic.sv @@ -36,7 +36,9 @@ module rv_plic import rv_plic_reg_pkg::*; #( input tlul_pkg::tl_h2d_t tl_i, output tlul_pkg::tl_d2h_t tl_o, - // Interrupt Sources + // Interrupt Sources. Note that the lowest bit must be tied to 0 because it + // is reserved for "no interrupt". Because the lowest bit is always 0, + // only NumSrc-1 interrupts are usable. input [NumSrc-1:0] intr_src_i, // Alerts @@ -430,8 +432,8 @@ module rv_plic import rv_plic_reg_pkg::*; #( `ASSERT_KNOWN(IrqIdKnownO_A, irq_id_o[k]) end - // Assume - `ASSUME(Irq0Tied_A, intr_src_i[0] == 1'b0) + // Bit 0 must be tied to zero because it is reserved for "no interrupt". + `ASSERT(Irq0Tied_A, intr_src_i[0] == 1'b0) // This assertion should be provable in FPV because we don't have a block-level DV environment. It // is trying to say that any integrity error detected inside the register block (u_reg) will cause diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/README.md b/hw/top_englishbreakfast/ip_autogen/rv_plic/README.md index 254925c96d1ba..71e58aad8da77 100644 --- a/hw/top_englishbreakfast/ip_autogen/rv_plic/README.md +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/README.md @@ -21,6 +21,9 @@ The RV_PLIC module is designed to manage various interrupt sources from the peripherals. It receives interrupt events as either edge or level of the incoming interrupt signals (``intr_src_i``) and can notify multiple targets. +Note that the lowest bit of ``intr_src_i`` is must be tied to 0 because it corresponds interrupt ID 0 which is reserved to mean "no interrupt". This is +verified with an assertion inside `rv_plic`. + ## Compatibility The RV_PLIC is compatible with any RISC-V core implementing the RISC-V privilege specification. diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic.hjson b/hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic.hjson index 00d94218b3f97..62af2cfb4101d 100644 --- a/hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic.hjson +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic.hjson @@ -42,7 +42,7 @@ param_list: [ { name: "NumSrc", - desc: "Number of interrupt sources", + desc: "Number of interrupt sources (including the 'no interrupt' ID 0)", type: "int", default: "88", local: "true" diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv b/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv index 8a64257766d71..38b0e4744dd60 100644 --- a/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv @@ -12,7 +12,7 @@ module rv_plic_tb import rv_plic_reg_pkg::*; #( input rst_ni, input tlul_pkg::tl_h2d_t [NumInstances-1:0] tl_i, output tlul_pkg::tl_d2h_t [NumInstances-1:0] tl_o, - input [NumInstances-1:0][NumSrc-1:0] intr_src_i, + input [NumInstances-1:0][NumSrc-2:0] intr_src_nonzero_i, input prim_alert_pkg::alert_rx_t [NumInstances-1:0][NumAlerts-1:0] alert_rx_i, output prim_alert_pkg::alert_tx_t [NumInstances-1:0][NumAlerts-1:0] alert_tx_o, output [NumInstances-1:0][NumTarget-1:0] irq_o, @@ -29,7 +29,8 @@ module rv_plic_tb import rv_plic_reg_pkg::*; #( .rst_ni , .tl_i (tl_i[0]), .tl_o (tl_o[0]), - .intr_src_i (intr_src_i[0]), + // Interrupt 0 must be tied to 0. + .intr_src_i ({intr_src_nonzero_i[0], 1'b0}), .alert_rx_i (alert_rx_i[0]), .alert_tx_o (alert_tx_o[0]), .irq_o (irq_o[0]), diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic.sv b/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic.sv index e25dafb0aa93e..538f9cc580c0c 100644 --- a/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic.sv +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic.sv @@ -36,7 +36,9 @@ module rv_plic import rv_plic_reg_pkg::*; #( input tlul_pkg::tl_h2d_t tl_i, output tlul_pkg::tl_d2h_t tl_o, - // Interrupt Sources + // Interrupt Sources. Note that the lowest bit must be tied to 0 because it + // is reserved for "no interrupt". Because the lowest bit is always 0, + // only NumSrc-1 interrupts are usable. input [NumSrc-1:0] intr_src_i, // Alerts @@ -332,8 +334,8 @@ module rv_plic import rv_plic_reg_pkg::*; #( `ASSERT_KNOWN(IrqIdKnownO_A, irq_id_o[k]) end - // Assume - `ASSUME(Irq0Tied_A, intr_src_i[0] == 1'b0) + // Bit 0 must be tied to zero because it is reserved for "no interrupt". + `ASSERT(Irq0Tied_A, intr_src_i[0] == 1'b0) // This assertion should be provable in FPV because we don't have a block-level DV environment. It // is trying to say that any integrity error detected inside the register block (u_reg) will cause