Allow for write enable and sticky property

This commit adds new type of fields: sticky with write enable.
This is used to gate status/interrupt register when one or more
interrupts aren't monitored.

Signed-off-by: Maciej Dudek <mdudek@antmicro.com>
This commit is contained in:
Maciej Dudek
2024-04-10 02:14:11 +02:00
committed by Alex Mykyta
parent a7cea87d40
commit 0a9a3ad51e
4 changed files with 423 additions and 45 deletions

View File

@@ -11,6 +11,15 @@ addrmap top {
ctrl_mask @ 0x104,
ctrl_haltenable @ 0x108,
ctrl_haltmask @ 0x10c;
reg {
field ctrl_t {
sw=rw; hw=na;
};
ctrl_t irq0[1] = 0;
ctrl_t irq1[1] = 0;
}
ctrl_we @ 0x110,
ctrl_wel @ 0x114;
//---------------------------------
reg {
@@ -35,6 +44,36 @@ addrmap top {
level_irqs_3.irq1->mask = ctrl_mask.irq1;
level_irqs_3.irq0->haltmask = ctrl_haltmask.irq0;
level_irqs_3.irq1->haltmask = ctrl_haltmask.irq1;
reg {
field intr_t {
sw=rw; hw=w;
level intr;
woclr;
we;
};
intr_t irq0[8] = 0;
intr_t irq1[1] = 0;
} level_irqs_we @ 0x10;
reg {
field intr_t {
sw=rw; hw=w;
level intr;
woclr;
wel;
};
intr_t irq0[8] = 0;
intr_t irq1[1] = 0;
} level_irqs_wel @ 0x14;
level_irqs_we.irq0->we = ctrl_we.irq0;
level_irqs_we.irq1->we = ctrl_we.irq1;
level_irqs_wel.irq0->wel = ctrl_wel.irq0;
level_irqs_wel.irq1->wel = ctrl_wel.irq1;
//---------------------------------
reg {
@@ -46,7 +85,35 @@ addrmap top {
intr_t irq0[8] = 0;
intr_t irq1[1] = 0;
} posedge_irqs @ 0x10;
} posedge_irqs @ 0x20;
reg {
field intr_t {
sw=rw; hw=w;
posedge intr;
woclr;
};
intr_t irq0[8] = 0;
intr_t irq1[1] = 0;
} posedge_we_irqs @ 0x24;
posedge_we_irqs.irq0->we = ctrl_we.irq0;
posedge_we_irqs.irq1->we = ctrl_we.irq1;
reg {
field intr_t {
sw=rw; hw=w;
posedge intr;
woclr;
};
intr_t irq0[8] = 0;
intr_t irq1[1] = 0;
} posedge_wel_irqs @ 0x28;
posedge_wel_irqs.irq0->wel = ctrl_wel.irq0;
posedge_wel_irqs.irq1->wel = ctrl_wel.irq1;
//---------------------------------
@@ -59,7 +126,35 @@ addrmap top {
intr_t irq0[8] = 0;
intr_t irq1[1] = 0;
} negedge_irqs @ 0x20;
} negedge_irqs @ 0x30;
reg {
field intr_t {
sw=rw; hw=w;
negedge intr;
woclr;
};
intr_t irq0[8] = 0;
intr_t irq1[1] = 0;
} negedge_we_irqs @ 0x34;
negedge_we_irqs.irq0->we = ctrl_we.irq0;
negedge_we_irqs.irq1->we = ctrl_we.irq1;
reg {
field intr_t {
sw=rw; hw=w;
negedge intr;
woclr;
};
intr_t irq0[8] = 0;
intr_t irq1[1] = 0;
} negedge_wel_irqs @ 0x38;
negedge_wel_irqs.irq0->wel = ctrl_wel.irq0;
negedge_wel_irqs.irq1->wel = ctrl_wel.irq1;
//---------------------------------
@@ -72,7 +167,35 @@ addrmap top {
intr_t irq0[8] = 0;
intr_t irq1[1] = 0;
} bothedge_irqs @ 0x30;
} bothedge_irqs @ 0x40;
reg {
field intr_t {
sw=rw; hw=w;
bothedge intr;
woclr;
};
intr_t irq0[8] = 0;
intr_t irq1[1] = 0;
} bothedge_we_irqs @ 0x44;
bothedge_we_irqs.irq0->we = ctrl_we.irq0;
bothedge_we_irqs.irq1->we = ctrl_we.irq1;
reg {
field intr_t {
sw=rw; hw=w;
bothedge intr;
woclr;
};
intr_t irq0[8] = 0;
intr_t irq1[1] = 0;
} bothedge_wel_irqs @ 0x48;
bothedge_wel_irqs.irq0->wel = ctrl_wel.irq0;
bothedge_wel_irqs.irq1->wel = ctrl_wel.irq1;
//---------------------------------
@@ -87,7 +210,7 @@ addrmap top {
intr_t negedge_active[1];
intr_t bothedge_active[1];
intr_t level_halt_active[1];
} top_irq @ 0x40;
} top_irq @ 0x50;
top_irq.level_active->next = level_irqs_1->intr;
top_irq.posedge_active->next = posedge_irqs->intr;
@@ -101,6 +224,6 @@ addrmap top {
sw=rw; hw=w;
sticky;
} stickyfield[8] = 0;
} stickyreg @ 0x50;
} stickyreg @ 0x60;
};

View File

@@ -11,6 +11,8 @@
cpuif.write('h104, 'h000); // ctrl_mask
cpuif.write('h108, 'h1FF); // ctrl_haltenable
cpuif.write('h10C, 'h000); // ctrl_haltmask
cpuif.write('h110, 'h0); // ctrl_we
cpuif.write('h114, 'h3); // ctrl_wel
//--------------------------------------------------------------------------
// Test level_irqs_1
@@ -106,99 +108,154 @@
assert(cb.hwif_out.level_irqs_3.halt == 1'b1);
//--------------------------------------------------------------------------
// Test posedge_irqs
// Test level_irqs with we
cpuif.assert_read('h10, 'h000);
assert(cb.hwif_out.level_irqs_we.intr == 1'b0);
cb.hwif_in.level_irqs_we.irq0.next <= 'h0F;
assert(cb.hwif_in.level_irqs_we.irq0.next == 8'h00);
@cb;
cb.hwif_in.level_irqs_we.irq0.next <= 'h00;
assert(cb.hwif_out.level_irqs_we.intr == 1'b0);
cpuif.assert_read('h10, 'h000);
cpuif.write('h110, 'h1); // enable ctrl_we
@cb;
cpuif.assert_read('h110, 'h1);
assert(cb.hwif_out.level_irqs_we.intr == 1'b0);
cb.hwif_in.level_irqs_we.irq0.next <= 'h0F;
@cb;
assert(cb.hwif_in.level_irqs_we.irq0.next == 8'h0F);
cpuif.assert_read('h10, 'h00F);
assert(cb.hwif_out.level_irqs_we.intr == 1'b1);
cpuif.write('h110, 'h0); // disable ctrl_we
cpuif.write('h10, 'h1FF);
@cb;
assert(cb.hwif_out.level_irqs_we.intr == 1'b0);
cpuif.assert_read('h10, 'h000);
cb.hwif_in.level_irqs_we.irq0.next <= 'h00;
//--------------------------------------------------------------------------
// Test level_irqs with wel
cpuif.assert_read('h14, 'h000);
assert(cb.hwif_out.level_irqs_wel.intr == 1'b0);
cb.hwif_in.level_irqs_wel.irq0.next <= 'h0F;
assert(cb.hwif_in.level_irqs_wel.irq0.next == 8'h00);
@cb;
cb.hwif_in.level_irqs_wel.irq0.next <= 'h00;
cpuif.assert_read('h14, 'h000);
assert(cb.hwif_in.level_irqs_wel.irq0.next == 8'h00);
assert(cb.hwif_out.level_irqs_wel.intr == 1'b0);
cpuif.write('h114, 'h2); // enable ctrl_we
@cb;
cpuif.assert_read('h14, 'h000);
assert(cb.hwif_in.level_irqs_wel.irq0.next == 8'h00);
assert(cb.hwif_out.level_irqs_wel.intr == 1'b0);
cb.hwif_in.level_irqs_wel.irq0.next <= 'h0F;
@cb;
assert(cb.hwif_in.level_irqs_wel.irq0.next == 8'h0F);
cpuif.assert_read('h14, 'h00F);
assert(cb.hwif_out.level_irqs_wel.intr == 1'b1);
cpuif.write('h114, 'h3); // disable ctrl_we
cpuif.write('h14, 'h1FF);
@cb;
assert(cb.hwif_out.level_irqs_wel.intr == 1'b0);
cpuif.assert_read('h14, 'h000);
cb.hwif_in.level_irqs_wel.irq0.next <= 'h00;
//--------------------------------------------------------------------------
// Test posedge_irqs
cpuif.assert_read('h20, 'h000);
assert(cb.hwif_out.posedge_irqs.intr == 1'b0);
cb.hwif_in.posedge_irqs.irq1.next <= 1'b1;
@cb;
cpuif.assert_read('h10, 'h100);
cpuif.assert_read('h20, 'h100);
assert(cb.hwif_out.posedge_irqs.intr == 1'b1);
cpuif.write('h10, 'h100);
cpuif.assert_read('h10, 'h000);
cpuif.write('h20, 'h100);
cpuif.assert_read('h20, 'h000);
assert(cb.hwif_out.posedge_irqs.intr == 1'b0);
cpuif.assert_read('h10, 'h000);
cpuif.assert_read('h20, 'h000);
cb.hwif_in.posedge_irqs.irq1.next <= 1'b0;
cpuif.assert_read('h10, 'h000);
cpuif.assert_read('h20, 'h000);
assert(cb.hwif_out.posedge_irqs.intr == 1'b0);
//--------------------------------------------------------------------------
// Test negedge_irqs
cpuif.assert_read('h20, 'h000);
cpuif.assert_read('h30, 'h000);
assert(cb.hwif_out.negedge_irqs.intr == 1'b0);
cb.hwif_in.negedge_irqs.irq1.next <= 1'b1;
@cb;
cpuif.assert_read('h20, 'h000);
cpuif.assert_read('h30, 'h000);
assert(cb.hwif_out.negedge_irqs.intr == 1'b0);
cb.hwif_in.negedge_irqs.irq1.next <= 1'b0;
cpuif.assert_read('h20, 'h100);
cpuif.assert_read('h30, 'h100);
assert(cb.hwif_out.negedge_irqs.intr == 1'b1);
cpuif.write('h20, 'h100);
cpuif.assert_read('h20, 'h000);
cpuif.write('h30, 'h100);
cpuif.assert_read('h30, 'h000);
assert(cb.hwif_out.negedge_irqs.intr == 1'b0);
cpuif.assert_read('h20, 'h000);
cpuif.assert_read('h30, 'h000);
//--------------------------------------------------------------------------
// Test bothedge_irqs
cpuif.assert_read('h30, 'h000);
cpuif.assert_read('h40, 'h000);
assert(cb.hwif_out.bothedge_irqs.intr == 1'b0);
cb.hwif_in.bothedge_irqs.irq1.next <= 1'b1;
cpuif.assert_read('h30, 'h100);
cpuif.assert_read('h40, 'h100);
assert(cb.hwif_out.bothedge_irqs.intr == 1'b1);
cpuif.write('h30, 'h100);
cpuif.assert_read('h30, 'h000);
cpuif.write('h40, 'h100);
cpuif.assert_read('h40, 'h000);
assert(cb.hwif_out.bothedge_irqs.intr == 1'b0);
cpuif.assert_read('h30, 'h000);
cpuif.assert_read('h40, 'h000);
cb.hwif_in.bothedge_irqs.irq1.next <= 1'b0;
cpuif.assert_read('h30, 'h100);
cpuif.assert_read('h40, 'h100);
assert(cb.hwif_out.bothedge_irqs.intr == 1'b1);
cpuif.write('h30, 'h100);
cpuif.assert_read('h30, 'h000);
cpuif.write('h40, 'h100);
cpuif.assert_read('h40, 'h000);
assert(cb.hwif_out.bothedge_irqs.intr == 1'b0);
cpuif.assert_read('h30, 'h000);
cpuif.assert_read('h40, 'h000);
//--------------------------------------------------------------------------
cpuif.assert_read('h40, 'h000);
// Test top_irq
cpuif.assert_read('h50, 'h000);
assert(cb.hwif_out.top_irq.intr == 1'b0);
cb.hwif_in.level_irqs_1.irq0.next <= 'h01;
@cb;
cb.hwif_in.level_irqs_1.irq0.next <= 'h00;
cpuif.assert_read('h40, 'b0001);
cpuif.assert_read('h50, 'b0001);
assert(cb.hwif_out.top_irq.intr == 1'b1);
cpuif.write('h0, 'h01);
cpuif.assert_read('h40, 'b0000);
cpuif.assert_read('h50, 'b0000);
assert(cb.hwif_out.top_irq.intr == 1'b0);
cb.hwif_in.posedge_irqs.irq0.next <= 'h01;
@cb;
cb.hwif_in.posedge_irqs.irq0.next <= 'h00;
cpuif.assert_read('h40, 'b0010);
cpuif.assert_read('h50, 'b0010);
assert(cb.hwif_out.top_irq.intr == 1'b1);
cpuif.write('h10, 'h01);
cpuif.assert_read('h40, 'b0000);
cpuif.write('h20, 'h01);
cpuif.assert_read('h50, 'b0000);
assert(cb.hwif_out.top_irq.intr == 1'b0);
cb.hwif_in.negedge_irqs.irq0.next <= 'h01;
@cb;
cb.hwif_in.negedge_irqs.irq0.next <= 'h00;
@cb;
cpuif.assert_read('h40, 'b0100);
cpuif.assert_read('h50, 'b0100);
assert(cb.hwif_out.top_irq.intr == 1'b1);
cpuif.write('h20, 'h01);
cpuif.assert_read('h40, 'b0000);
cpuif.write('h30, 'h01);
cpuif.assert_read('h50, 'b0000);
assert(cb.hwif_out.top_irq.intr == 1'b0);
cb.hwif_in.bothedge_irqs.irq0.next <= 'h01;
@cb;
cb.hwif_in.bothedge_irqs.irq0.next <= 'h00;
cpuif.assert_read('h40, 'b1000);
cpuif.assert_read('h50, 'b1000);
assert(cb.hwif_out.top_irq.intr == 1'b1);
cpuif.write('h30, 'h01);
cpuif.assert_read('h40, 'b0000);
cpuif.write('h40, 'h01);
cpuif.assert_read('h50, 'b0000);
assert(cb.hwif_out.top_irq.intr == 1'b0);
cpuif.write('h108, 'h000); // ctrl_haltenable
@@ -206,32 +263,32 @@
@cb;
cb.hwif_in.level_irqs_2.irq0.next <= 'h00;
@cb;
cpuif.assert_read('h40, 'b00000);
cpuif.assert_read('h50, 'b00000);
assert(cb.hwif_out.top_irq.intr == 1'b0);
cpuif.write('h108, 'h001); // ctrl_haltenable
cpuif.assert_read('h40, 'b10000);
cpuif.assert_read('h50, 'b10000);
assert(cb.hwif_out.top_irq.intr == 1'b1);
cpuif.write('h4, 'h01);
cpuif.assert_read('h40, 'b00000);
cpuif.assert_read('h50, 'b00000);
assert(cb.hwif_out.top_irq.intr == 1'b0);
//--------------------------------------------------------------------------
// Test multi-bit sticky reg
cpuif.assert_read('h50, 'h00);
cpuif.assert_read('h60, 'h00);
cb.hwif_in.stickyreg.stickyfield.next <= 'h12;
@cb;
cb.hwif_in.stickyreg.stickyfield.next <= 'h34;
@cb;
cb.hwif_in.stickyreg.stickyfield.next <= 'h56;
@cb;
cpuif.assert_read('h50, 'h12);
cpuif.write('h50, 'h00);
cpuif.assert_read('h60, 'h12);
cpuif.write('h60, 'h00);
@cb;
cb.hwif_in.stickyreg.stickyfield.next <= 'h78;
@cb;
cpuif.assert_read('h50, 'h56);
cpuif.assert_read('h60, 'h56);
{% endblock %}