Skip to content

Commit

Permalink
[adc_ctrl] Change collated IRQ to status type
Browse files Browse the repository at this point in the history
Addresses part of lowRISC#21832

Signed-off-by: Michael Schaffner <[email protected]>
  • Loading branch information
msfschaffner committed Mar 6, 2024
1 parent 4c06f37 commit cf4996e
Show file tree
Hide file tree
Showing 11 changed files with 43 additions and 19 deletions.
1 change: 1 addition & 0 deletions hw/ip/adc_ctrl/data/adc_ctrl.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
interrupt_list: [
{ name: "match_done",
desc: "ADC match or measurement event done",
type: "status"
}
],
alert_list: [
Expand Down
2 changes: 1 addition & 1 deletion hw/ip/adc_ctrl/doc/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Referring to the [Comportable guideline for peripheral device functionality](htt

| Interrupt Name | Type | Description |
|:-----------------|:-------|:------------------------------------|
| match_done | Event | ADC match or measurement event done |
| match_done | Status | ADC match or measurement event done |

## Security Alerts

Expand Down
4 changes: 2 additions & 2 deletions hw/ip/adc_ctrl/doc/registers.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ Interrupt State Register
### Fields

```wavejson
{"reg": [{"name": "match_done", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 120}}
{"reg": [{"name": "match_done", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 120}}
```

| Bits | Type | Reset | Name | Description |
|:------:|:------:|:-------:|:-----------|:------------------------------------|
| 31:1 | | | | Reserved |
| 0 | rw1c | 0x0 | match_done | ADC match or measurement event done |
| 0 | ro | 0x0 | match_done | ADC match or measurement event done |

## INTR_ENABLE
Interrupt Enable Register
Expand Down
5 changes: 4 additions & 1 deletion hw/ip/adc_ctrl/rtl/adc_ctrl_intr.sv
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,10 @@ module adc_ctrl_intr
assign adc_intr_status_o.oneshot.d = 1'b1;

// instantiate interrupt hardware primitive
prim_intr_hw #(.Width(1)) i_adc_ctrl_intr_o (
prim_intr_hw #(
.Width(1),
.IntrT("Status")
) i_adc_ctrl_intr_o (
.clk_i(clk_i),
.rst_ni(rst_ni),
.event_intr_i (|intr_events),
Expand Down
13 changes: 4 additions & 9 deletions hw/ip/adc_ctrl/rtl/adc_ctrl_reg_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,7 @@ module adc_ctrl_reg_top (
// Define SW related signals
// Format: <reg>_<field>_{wd|we|qs}
// or <reg>_{wd|we|qs} if field == 1 or 0
logic intr_state_we;
logic intr_state_qs;
logic intr_state_wd;
logic intr_enable_we;
logic intr_enable_qs;
logic intr_enable_wd;
Expand Down Expand Up @@ -1356,16 +1354,16 @@ module adc_ctrl_reg_top (
// R[intr_state]: V(False)
prim_subreg #(
.DW (1),
.SwAccess(prim_subreg_pkg::SwAccessW1C),
.SwAccess(prim_subreg_pkg::SwAccessRO),
.RESVAL (1'h0),
.Mubi (1'b0)
) u_intr_state (
.clk_i (clk_i),
.rst_ni (rst_ni),

// from register interface
.we (intr_state_we),
.wd (intr_state_wd),
.we (1'b0),
.wd ('0),

// from internal hardware
.de (hw2reg.intr_state.de),
Expand Down Expand Up @@ -4050,9 +4048,6 @@ module adc_ctrl_reg_top (
end

// Generate write-enables
assign intr_state_we = addr_hit[0] & reg_we & !reg_error;

assign intr_state_wd = reg_wdata[0];
assign intr_enable_we = addr_hit[1] & reg_we & !reg_error;

assign intr_enable_wd = reg_wdata[0];
Expand Down Expand Up @@ -4180,7 +4175,7 @@ module adc_ctrl_reg_top (
// Assign write-enables to checker logic vector.
always_comb begin
reg_we_check = '0;
reg_we_check[0] = intr_state_we;
reg_we_check[0] = 1'b0;
reg_we_check[1] = intr_enable_we;
reg_we_check[2] = intr_test_we;
reg_we_check[3] = alert_test_we;
Expand Down
2 changes: 1 addition & 1 deletion hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -14291,7 +14291,7 @@
width: 1
type: interrupt
module_name: adc_ctrl_aon
intr_type: IntrType.Event
intr_type: IntrType.Status
default_val: false
}
{
Expand Down
2 changes: 1 addition & 1 deletion sw/device/lib/dif/autogen/dif_adc_ctrl_autogen.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static bool adc_ctrl_get_irq_bit_index(dif_adc_ctrl_irq_t irq,
}

static dif_irq_type_t irq_types[] = {
kDifIrqTypeEvent,
kDifIrqTypeStatus,
};

OT_WARN_UNUSED_RESULT
Expand Down
2 changes: 1 addition & 1 deletion sw/device/lib/dif/autogen/dif_adc_ctrl_autogen_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ TEST_F(IrqGetTypeTest, Success) {

EXPECT_DIF_OK(
dif_adc_ctrl_irq_get_type(&adc_ctrl_, kDifAdcCtrlIrqMatchDone, &type));
EXPECT_EQ(type, kDifIrqTypeEvent);
EXPECT_EQ(type, kDifIrqTypeStatus);
}

class IrqGetStateTest : public AdcCtrlTest {};
Expand Down
5 changes: 4 additions & 1 deletion sw/device/lib/testing/autogen/isr_testutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

void isr_testutils_adc_ctrl_isr(
plic_isr_ctx_t plic_ctx, adc_ctrl_isr_ctx_t adc_ctrl_ctx,
top_earlgrey_plic_peripheral_t *peripheral_serviced,
bool mute_status_irq, top_earlgrey_plic_peripheral_t *peripheral_serviced,
dif_adc_ctrl_irq_t *irq_serviced) {
// Claim the IRQ at the PLIC.
dif_rv_plic_irq_id_t plic_irq_id;
Expand Down Expand Up @@ -75,6 +75,9 @@ void isr_testutils_adc_ctrl_isr(
CHECK_DIF_OK(dif_adc_ctrl_irq_get_type(adc_ctrl_ctx.adc_ctrl, irq, &type));
if (type == kDifIrqTypeEvent) {
CHECK_DIF_OK(dif_adc_ctrl_irq_acknowledge(adc_ctrl_ctx.adc_ctrl, irq));
} else if (mute_status_irq) {
CHECK_DIF_OK(dif_adc_ctrl_irq_set_enabled(adc_ctrl_ctx.adc_ctrl, irq,
kDifToggleDisabled));
}

// Complete the IRQ at the PLIC.
Expand Down
3 changes: 2 additions & 1 deletion sw/device/lib/testing/autogen/isr_testutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -565,13 +565,14 @@ typedef struct usbdev_isr_ctx {
*
* @param plic_ctx A PLIC ISR context handle.
* @param adc_ctrl_ctx A(n) adc_ctrl ISR context handle.
* @param mute_status_irq set to true to disable the serviced status type IRQ.
* @param[out] peripheral_serviced Out param for the peripheral that was
* serviced.
* @param[out] irq_serviced Out param for the IRQ that was serviced.
*/
void isr_testutils_adc_ctrl_isr(
plic_isr_ctx_t plic_ctx, adc_ctrl_isr_ctx_t adc_ctrl_ctx,
top_earlgrey_plic_peripheral_t *peripheral_serviced,
bool mute_status_irq, top_earlgrey_plic_peripheral_t *peripheral_serviced,
dif_adc_ctrl_irq_t *irq_serviced);

/**
Expand Down
23 changes: 22 additions & 1 deletion sw/device/tests/autogen/plic_all_irqs_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,19 @@ void ottf_external_isr(uint32_t *exc_info) {
"Only adc_ctrl_aon IRQ %d expected to fire. Actual interrupt "
"status = %x", irq, snapshot);

CHECK_DIF_OK(dif_adc_ctrl_irq_acknowledge(&adc_ctrl_aon, irq));
// If this is a status type interrupt, we do not have to acknowledge the interrupt at
// the IP side, but we need to clear the test force register.
if (0x1 & (1 << irq)) {
CHECK_DIF_OK(dif_adc_ctrl_irq_force(&adc_ctrl_aon, irq, false));
// In case this status interrupt is asserted by default, we also disable it at
// this point so that it does not interfere with the rest of the test.
if ((0x0 & (1 << irq))) {
CHECK_DIF_OK(dif_adc_ctrl_irq_set_enabled(&adc_ctrl_aon, irq, false));
}
// If this is a regular event type interrupt, we acknowledge it at this point.
} else {
CHECK_DIF_OK(dif_adc_ctrl_irq_acknowledge(&adc_ctrl_aon, irq));
}
break;
}
#endif
Expand Down Expand Up @@ -1728,13 +1740,22 @@ static void peripheral_irqs_trigger(void) {

#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL
peripheral_expected = kTopEarlgreyPlicPeripheralAdcCtrlAon;
status_default_mask = 0x0;
for (dif_adc_ctrl_irq_t irq = kDifAdcCtrlIrqMatchDone;
irq <= kDifAdcCtrlIrqMatchDone; ++irq) {

adc_ctrl_irq_expected = irq;
LOG_INFO("Triggering adc_ctrl_aon IRQ %d.", irq);
CHECK_DIF_OK(dif_adc_ctrl_irq_force(&adc_ctrl_aon, irq, true));

// In this case, the interrupt has not been enabled yet because that would
// interfere with testing other interrupts. We enable it here and let the
// interrupt handler disable it again.
if ((status_default_mask & 0x1)) {
CHECK_DIF_OK(dif_adc_ctrl_irq_set_enabled(&adc_ctrl_aon, irq, true));
}
status_default_mask >>= 1;

// This avoids a race where *irq_serviced is read before
// entering the ISR.
IBEX_SPIN_FOR(adc_ctrl_irq_serviced == irq, 1);
Expand Down

0 comments on commit cf4996e

Please sign in to comment.