finish counters

This commit is contained in:
Alex Mykyta
2021-12-11 23:37:00 -08:00
parent 9eddc9b60f
commit 3dee090467
9 changed files with 238 additions and 11 deletions

View File

@@ -217,17 +217,17 @@ asserted if the counter value is greater or equal to the threshold.
boolean
|EX|
|OK|
If true, threshold is the counter's maximum count value. (2^width - 1)
integer
|EX|
|OK|
Specify a static threshold value.
reference
|EX|
|OK|
Specify a dynamic threshold value.
@@ -252,7 +252,7 @@ property defines the signal's width.
overflow
^^^^^^^^
|EX|
|OK|
If true, infers an output signal ``hwif_out..overflow`` that is asserted when
the counter is about to wrap.
@@ -323,17 +323,17 @@ asserted if the counter value is less than or equal to the threshold.
boolean
|EX|
|OK|
If true, threshold is 0.
integer
|EX|
|OK|
Specify a static threshold value.
reference
|EX|
|OK|
Specify a dynamic threshold value.
@@ -357,7 +357,7 @@ property defines the signal's width.
underflow
^^^^^^^^^
|EX|
|OK|
If true, infers an output signal ``hwif_out..underflow`` that is asserted when
the counter is about to wrap.

View File

@@ -177,3 +177,16 @@ class FieldLogicGenerator(RDLForLoopGenerator):
self.add_content(
f"assign {output_identifier} = {value};"
)
if node.get_property('overflow'):
output_identifier = self.exp.hwif.get_implied_prop_output_identifier(node, "overflow")
value = self.field_logic.get_field_combo_identifier(node, 'overflow')
self.add_content(
f"assign {output_identifier} = {value};"
)
if node.get_property('underflow'):
output_identifier = self.exp.hwif.get_implied_prop_output_identifier(node, "underflow")
value = self.field_logic.get_field_combo_identifier(node, 'underflow')
self.add_content(
f"assign {output_identifier} = {value};"
)

View File

@@ -291,6 +291,9 @@ class Hwif:
def get_implied_prop_output_identifier(self, field: FieldNode, prop: str) -> str:
assert prop in {"anded", "ored", "xored", "swmod", "swacc"}
assert prop in {
"anded", "ored", "xored", "swmod", "swacc",
"incrthreshold", "decrthreshold", "overflow", "underflow"
}
path = get_indexed_path(self.top_node, field)
return "hwif_out." + path + "." + prop

View File

@@ -12,9 +12,10 @@ addrmap top {
decrvalue=1;
} down[11:8] = 0x4;
field {
sw=r; hw=na; counter;
sw=r; hw=r; counter;
incrvalue=1;
decrvalue=1;
overflow; underflow;
} updown[15:12] = 0;
field {

View File

@@ -49,6 +49,61 @@
cb.hwif_in.simple.updown.incr <= '0;
cpuif.assert_read('h0, 'h0000, 'hF000);
// up/down external underflow
fork
begin
##0;
forever begin
assert(cb.hwif_out.simple.updown.value == 0);
if(cb.hwif_out.simple.updown.underflow) break;
@cb;
end
@cb;
forever begin
assert(cb.hwif_out.simple.updown.value == 15);
assert(cb.hwif_out.simple.updown.underflow == 0);
@cb;
end
end
begin
repeat(2) @cb;
cb.hwif_in.simple.updown.decr <= '1;
@cb;
cb.hwif_in.simple.updown.decr <= '0;
repeat(2) @cb;
end
join_any
disable fork;
// up/down external overflow
fork
begin
##0;
forever begin
assert(cb.hwif_out.simple.updown.value == 15);
if(cb.hwif_out.simple.updown.overflow) break;
@cb;
end
@cb;
forever begin
assert(cb.hwif_out.simple.updown.value == 0);
assert(cb.hwif_out.simple.updown.overflow == 0);
@cb;
end
end
begin
repeat(2) @cb;
cb.hwif_in.simple.updown.incr <= '1;
@cb;
cb.hwif_in.simple.updown.incr <= '0;
repeat(2) @cb;
end
join_any
disable fork;
// up/down via sw
cpuif.assert_read('h0, 'h00000, 'hF0000);
repeat(3) cpuif.write('h0, 'h4000_0000); // incr
@@ -89,5 +144,4 @@
cpuif.assert_read('h0, 'h8000000, 'hF000000);
repeat(2) cpuif.write('h0, 'h8000_0000 + (2'h3 << 28)); // - 3
cpuif.assert_read('h0, 'h2000000, 'hF000000);
{% endblock %}

View File

View File

@@ -0,0 +1,36 @@
addrmap top {
reg {
field {
sw=r; hw=r; counter;
incrthreshold;
decrthreshold;
} count[4] = 0;
} threshold_via_bool @ 0x0;
reg {
field {
sw=r; hw=r; counter;
incrthreshold = 10;
decrthreshold = 5;
} count[4] = 0;
} threshold_via_const @ 0x4;
reg {
field {
sw=r; hw=r; counter;
} count[4] = 0;
} threshold_via_ref @ 0x8;
reg {
field {
sw=rw; hw=na;
} min[4] = 0x4;
field {
sw=rw; hw=na;
} max[4] = 0xB;
} threshold_control @ 0xC;
threshold_via_ref.count -> decrthreshold = threshold_control.min;
threshold_via_ref.count -> incrthreshold = threshold_control.max;
};

View File

@@ -0,0 +1,115 @@
{% extends "lib/tb_base.sv" %}
{% block seq %}
{% sv_line_anchor %}
##1;
cb.rst <= '0;
##1;
//--------------------------------------------------------------------------
// Test incrthreshold = true; incrthreshold = true;
//--------------------------------------------------------------------------
cpuif.assert_read('h0, 'h0);
fork
begin
forever begin
@cb;
if(cb.hwif_out.threshold_via_bool.count.value == 0)
assert(cb.hwif_out.threshold_via_bool.count.decrthreshold == 1'b1);
else
assert(cb.hwif_out.threshold_via_bool.count.decrthreshold == 1'b0);
if(cb.hwif_out.threshold_via_bool.count.value == 15)
assert(cb.hwif_out.threshold_via_bool.count.incrthreshold == 1'b1);
else
assert(cb.hwif_out.threshold_via_bool.count.incrthreshold == 1'b0);
end
end
begin
@cb;
cb.hwif_in.threshold_via_bool.count.incr <= '1;
repeat(32) @cb;
cb.hwif_in.threshold_via_bool.count.incr <= '0;
cb.hwif_in.threshold_via_bool.count.decr <= '1;
repeat(32) @cb;
cb.hwif_in.threshold_via_bool.count.decr <= '0;
@cb;
@cb;
end
join_any
disable fork;
//--------------------------------------------------------------------------
// Test incrthreshold = 10; incrthreshold = 5;
//--------------------------------------------------------------------------
cpuif.assert_read('h4, 'h0);
fork
begin
forever begin
@cb;
if(cb.hwif_out.threshold_via_const.count.value <= 5)
assert(cb.hwif_out.threshold_via_const.count.decrthreshold == 1'b1);
else
assert(cb.hwif_out.threshold_via_const.count.decrthreshold == 1'b0);
if(cb.hwif_out.threshold_via_const.count.value >= 10)
assert(cb.hwif_out.threshold_via_const.count.incrthreshold == 1'b1);
else
assert(cb.hwif_out.threshold_via_const.count.incrthreshold == 1'b0);
end
end
begin
@cb;
cb.hwif_in.threshold_via_const.count.incr <= '1;
repeat(32) @cb;
cb.hwif_in.threshold_via_const.count.incr <= '0;
cb.hwif_in.threshold_via_const.count.decr <= '1;
repeat(32) @cb;
cb.hwif_in.threshold_via_const.count.decr <= '0;
@cb;
@cb;
end
join_any
disable fork;
//--------------------------------------------------------------------------
// Test incrthreshold = ref; incrthreshold =ref;
//--------------------------------------------------------------------------
cpuif.assert_read('h8, 'h0);
fork
begin
forever begin
@cb;
if(cb.hwif_out.threshold_via_ref.count.value <= 4)
assert(cb.hwif_out.threshold_via_ref.count.decrthreshold == 1'b1);
else
assert(cb.hwif_out.threshold_via_ref.count.decrthreshold == 1'b0);
if(cb.hwif_out.threshold_via_ref.count.value >= 11)
assert(cb.hwif_out.threshold_via_ref.count.incrthreshold == 1'b1);
else
assert(cb.hwif_out.threshold_via_ref.count.incrthreshold == 1'b0);
end
end
begin
@cb;
cb.hwif_in.threshold_via_ref.count.incr <= '1;
repeat(32) @cb;
cb.hwif_in.threshold_via_ref.count.incr <= '0;
cb.hwif_in.threshold_via_ref.count.decr <= '1;
repeat(32) @cb;
cb.hwif_in.threshold_via_ref.count.decr <= '0;
@cb;
@cb;
end
join_any
disable fork;
{% endblock %}

View File

@@ -0,0 +1,5 @@
from ..lib.regblock_testcase import RegblockTestCase
class Test(RegblockTestCase):
def test_dut(self):
self.run_test()