Revise implementation of 'next' property

This commit is contained in:
Alex Mykyta
2021-12-20 12:21:51 -08:00
parent 769907404a
commit 8ed45ed632
8 changed files with 85 additions and 40 deletions

View File

@@ -102,10 +102,6 @@ X Signals marked as field_reset or cpuif_reset need to have activehigh/activelow
X incrvalue/decrvalue needs to be the same or narrower than counter itself
! singlepulse and next properties cannot both be used.
Both are hard overrides of the field's next value.
singlepulse is basically an alias for next=0 that takes lowest priority
! counter field that saturates should not set overflow
counter; incrsaturate; overflow;
counter; decrsaturate; underflow;
@@ -117,6 +113,7 @@ X incrvalue/decrvalue needs to be the same or narrower than counter itself
! incrwidth/decrwidth must be between 1 and the width of the counter
X field shall be hw writable if "next" is assigned.
================================================================================
Things that need validation by this exporter

View File

@@ -45,7 +45,7 @@ operation.
{signal: [
{name: 'clk', wave: 'p....'},
{name: 'hwif_in..value', wave: 'x.=x.', data: ['D']},
{name: 'hwif_in..next', wave: 'x.=x.', data: ['D']},
{name: 'hwif_out..swacc', wave: '0.10.'}
]}
@@ -106,7 +106,10 @@ hw
Controls hardware access to the field.
If readable, enables output signal ``hwif_out..value``. If writable, enables
input ``hwif_in..value``.
input ``hwif_in..next``.
Hardware-writable fields can optionally define the ``next`` property which replaces
the inferred ``hwif_in..next`` input with an alternate reference.
hwclr/hwset
@@ -140,7 +143,7 @@ If true, infers the existence of input signal: ``hwif_in..we``, ``hwif_in..wel``
{signal: [
{name: 'clk', wave: 'p....'},
{name: 'hwif_in..value', wave: 'x.=x.', data: ['D']},
{name: 'hwif_in..next', wave: 'x.=x.', data: ['D']},
{name: 'hwif_in..we', wave: '0.10.',},
{name: 'hwif_in..wel', wave: '1.01.',},
{name: '<field value>', wave: 'x..=.', data: ['D']}
@@ -390,10 +393,33 @@ the counter is about to wrap.
Interrupt Properties
--------------------
intr
^^^^
level (default)
|NO|
posedge
|NO|
negedge
|NO|
bothedge
|NO|
nonsticky
|NO|
enable
^^^^^^
|NO|
mask
^^^^
|NO|
haltenable
^^^^^^^^^^
|NO|
@@ -402,14 +428,6 @@ haltmask
^^^^^^^^
|NO|
intr
^^^^
|NO|
mask
^^^^
|NO|
sticky
^^^^^^
|NO|
@@ -430,7 +448,10 @@ encode
next
^^^^
|NO|
|OK|
If assigned, replaces the inferred ``hwif_in..next`` input with an explicit reference.
paritycheck
^^^^^^^^^^^

View File

@@ -132,8 +132,13 @@ class Hwif:
raises an exception if obj is invalid
"""
if isinstance(obj, FieldNode):
next_value = obj.get_property('next')
if next_value is not None:
# 'next' property replaces the inferred input signal
return self.exp.dereferencer.get_value(next_value)
# Otherwise, use inferred
path = get_indexed_path(self.top_node, obj)
return "hwif_in." + path + ".value"
return "hwif_in." + path + ".next"
elif isinstance(obj, SignalNode):
if obj.get_path() in self.out_of_hier_signals:
return obj.inst_name

View File

@@ -30,9 +30,10 @@ class InputStructGenerator_Hier(RDLFlatStructGenerator):
type_name = self.get_typdef_name(node)
self.push_struct(type_name, node.inst_name)
# Provide input to field's value if it is writable by hw
if node.is_hw_writable:
self.add_member("value", node.width)
# Provide input to field's next value if it is writable by hw, and it
# was not overridden by the 'next' property
if node.is_hw_writable and node.get_property('next') is None:
self.add_member("next", node.width)
# Generate implied inputs
for prop_name in ["we", "wel", "swwe", "swwel", "hwclr", "hwset"]:

View File

@@ -15,13 +15,13 @@
cpuif.assert_read('h0, 11);
assert(cb.hwif_out.r1.f.value == 11);
cb.hwif_in.r1.f.value <= 9;
cb.hwif_in.r1.f.next <= 9;
cpuif.assert_read('h0, 11);
assert(cb.hwif_out.r1.f.value == 11);
cb.hwif_in.r1.f.value <= 12;
cb.hwif_in.r1.f.next <= 12;
cb.hwif_in.r1.f.we <= 1;
@cb;
cb.hwif_in.r1.f.value <= 0;
cb.hwif_in.r1.f.next <= 0;
cb.hwif_in.r1.f.we <= 0;
cpuif.assert_read('h0, 12);
assert(cb.hwif_out.r1.f.value == 12);
@@ -42,12 +42,12 @@
cpuif.write('h2, 31);
cpuif.assert_read('h2, 31);
cb.hwif_in.r3.f.value <= 29;
cb.hwif_in.r3.f.next <= 29;
cpuif.assert_read('h2, 31);
cb.hwif_in.r3.f.value <= 32;
cb.hwif_in.r3.f.next <= 32;
cb.hwif_in.r3.f.wel <= 0;
@cb;
cb.hwif_in.r3.f.value <= 0;
cb.hwif_in.r3.f.next <= 0;
cb.hwif_in.r3.f.wel <= 1;
cpuif.assert_read('h2, 32);
@@ -66,13 +66,13 @@
cpuif.assert_read('h4, 50);
assert(cb.hwif_out.r5.f.value == 50);
cb.hwif_in.r5.f.value <= 9;
cb.hwif_in.r5.f.next <= 9;
cpuif.assert_read('h4, 50);
assert(cb.hwif_out.r5.f.value == 50);
cb.hwif_in.r5.f.value <= 52;
cb.hwif_in.r5.f.next <= 52;
cb.hwif_in.r5.f.we <= 1;
@cb;
cb.hwif_in.r5.f.value <= 0;
cb.hwif_in.r5.f.next <= 0;
cb.hwif_in.r5.f.we <= 0;
cpuif.assert_read('h4, 52);
assert(cb.hwif_out.r5.f.value == 52);
@@ -88,7 +88,7 @@
// r7 - sw=r; hw=w; // Wire/Bus - hardware assigns value
cpuif.assert_read('h6, 0);
cb.hwif_in.r7.f.value <= 70;
cb.hwif_in.r7.f.next <= 70;
cpuif.assert_read('h6, 70);
cpuif.write('h6, 71);
cpuif.assert_read('h6, 70);
@@ -108,13 +108,13 @@
cpuif.assert_read('h8, 0);
assert(cb.hwif_out.r9.f.value == 91);
cb.hwif_in.r9.f.value <= 89;
cb.hwif_in.r9.f.next <= 89;
cpuif.assert_read('h8, 0);
assert(cb.hwif_out.r9.f.value == 91);
cb.hwif_in.r9.f.value <= 92;
cb.hwif_in.r9.f.next <= 92;
cb.hwif_in.r9.f.we <= 1;
@cb;
cb.hwif_in.r9.f.value <= 0;
cb.hwif_in.r9.f.next <= 0;
cb.hwif_in.r9.f.we <= 0;
cpuif.assert_read('h8, 0);
assert(cb.hwif_out.r9.f.value == 92);

View File

@@ -60,4 +60,14 @@ addrmap top {
} f[7:0] = 0x44;
} r4;
r4.f->wel = hw_ctrl.hw_wel;
reg {
signal {} f_next_value[8];
signal {} f_we;
field {
sw=rw; hw=w;
next = f_next_value;
we = f_we;
} f[7:0] = 0x55;
} r5;
};

View File

@@ -16,7 +16,7 @@
cpuif.write('h0, 'h00_F0);
// test hwenable + we
cb.hwif_in.r1.f.value <= 'hAB;
cb.hwif_in.r1.f.next <= 'hAB;
cb.hwif_in.r1.f.we <= '1;
@cb;
cb.hwif_in.r1.f.we <= '0;
@@ -40,7 +40,7 @@
cpuif.write('h0, 'hF0_00);
// test hwmask + we
cb.hwif_in.r2.f.value <= 'hAB;
cb.hwif_in.r2.f.next <= 'hAB;
cb.hwif_in.r2.f.we <= '1;
@cb;
cb.hwif_in.r2.f.we <= '0;
@@ -72,7 +72,7 @@
cpuif.assert_read('hC, 'h0F);
// test hwenable + we via reference
cb.hwif_in.r3.f.value <= 'hAA;
cb.hwif_in.r3.f.next <= 'hAA;
// toggle hwenable = 0F, we=1
cpuif.write('h0, 'h4_00_0F);
cpuif.write('h0, 'h0_00_00);
@@ -80,15 +80,26 @@
//---------------------------------
// test wel via reference
cb.hwif_in.r4.f.value <= 'hBB;
cb.hwif_in.r4.f.next <= 'hBB;
// toggle wel
cpuif.write('h0, 'h10_00_00);
cpuif.write('h0, 'h00_00_00);
cpuif.assert_read('h10, 'hBB);
cb.hwif_in.r4.f.value <= 'hCC;
cb.hwif_in.r4.f.next <= 'hCC;
// toggle wel
cpuif.write('h0, 'h10_00_00);
cpuif.write('h0, 'h00_00_00);
cpuif.assert_read('h10, 'hCC);
//---------------------------------
// test we and next via reference
cb.hwif_in.r5.f_next_value <= 'h54;
cpuif.assert_read('h14, 'h55);
cb.hwif_in.r5.f_next_value <= 'h56;
cb.hwif_in.r5.f_we <= '1;
@cb;
cb.hwif_in.r5.f_next_value <= '0;
cb.hwif_in.r5.f_we <= '0;
cpuif.assert_read('h14, 'h56);
{% endblock %}

View File

@@ -14,7 +14,7 @@
// Verify that hwif gets sampled at the same cycle as swacc strobe
counter = 'h10;
cb.hwif_in.r1.f.value <= counter;
cb.hwif_in.r1.f.next <= counter;
@cb;
event_count = 0;
fork
@@ -22,7 +22,7 @@
##0;
forever begin
counter++;
cb.hwif_in.r1.f.value <= counter;
cb.hwif_in.r1.f.next <= counter;
@cb;
if(cb.hwif_out.r1.f.swacc) begin
latched_data = counter;