Revise implementation of 'next' property
This commit is contained in:
@@ -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
|
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 field that saturates should not set overflow
|
||||||
counter; incrsaturate; overflow;
|
counter; incrsaturate; overflow;
|
||||||
counter; decrsaturate; underflow;
|
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
|
! 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
|
Things that need validation by this exporter
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ operation.
|
|||||||
|
|
||||||
{signal: [
|
{signal: [
|
||||||
{name: 'clk', wave: 'p....'},
|
{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.'}
|
{name: 'hwif_out..swacc', wave: '0.10.'}
|
||||||
]}
|
]}
|
||||||
|
|
||||||
@@ -106,7 +106,10 @@ hw
|
|||||||
Controls hardware access to the field.
|
Controls hardware access to the field.
|
||||||
|
|
||||||
If readable, enables output signal ``hwif_out..value``. If writable, enables
|
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
|
hwclr/hwset
|
||||||
@@ -140,7 +143,7 @@ If true, infers the existence of input signal: ``hwif_in..we``, ``hwif_in..wel``
|
|||||||
|
|
||||||
{signal: [
|
{signal: [
|
||||||
{name: 'clk', wave: 'p....'},
|
{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..we', wave: '0.10.',},
|
||||||
{name: 'hwif_in..wel', wave: '1.01.',},
|
{name: 'hwif_in..wel', wave: '1.01.',},
|
||||||
{name: '<field value>', wave: 'x..=.', data: ['D']}
|
{name: '<field value>', wave: 'x..=.', data: ['D']}
|
||||||
@@ -390,10 +393,33 @@ the counter is about to wrap.
|
|||||||
Interrupt Properties
|
Interrupt Properties
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
intr
|
||||||
|
^^^^
|
||||||
|
|
||||||
|
level (default)
|
||||||
|
|NO|
|
||||||
|
|
||||||
|
posedge
|
||||||
|
|NO|
|
||||||
|
|
||||||
|
negedge
|
||||||
|
|NO|
|
||||||
|
|
||||||
|
bothedge
|
||||||
|
|NO|
|
||||||
|
|
||||||
|
nonsticky
|
||||||
|
|NO|
|
||||||
|
|
||||||
|
|
||||||
enable
|
enable
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|NO|
|
|NO|
|
||||||
|
|
||||||
|
mask
|
||||||
|
^^^^
|
||||||
|
|NO|
|
||||||
|
|
||||||
haltenable
|
haltenable
|
||||||
^^^^^^^^^^
|
^^^^^^^^^^
|
||||||
|NO|
|
|NO|
|
||||||
@@ -402,14 +428,6 @@ haltmask
|
|||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|NO|
|
|NO|
|
||||||
|
|
||||||
intr
|
|
||||||
^^^^
|
|
||||||
|NO|
|
|
||||||
|
|
||||||
mask
|
|
||||||
^^^^
|
|
||||||
|NO|
|
|
||||||
|
|
||||||
sticky
|
sticky
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|NO|
|
|NO|
|
||||||
@@ -430,7 +448,10 @@ encode
|
|||||||
|
|
||||||
next
|
next
|
||||||
^^^^
|
^^^^
|
||||||
|NO|
|
|OK|
|
||||||
|
|
||||||
|
If assigned, replaces the inferred ``hwif_in..next`` input with an explicit reference.
|
||||||
|
|
||||||
|
|
||||||
paritycheck
|
paritycheck
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^
|
||||||
|
|||||||
@@ -132,8 +132,13 @@ class Hwif:
|
|||||||
raises an exception if obj is invalid
|
raises an exception if obj is invalid
|
||||||
"""
|
"""
|
||||||
if isinstance(obj, FieldNode):
|
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)
|
path = get_indexed_path(self.top_node, obj)
|
||||||
return "hwif_in." + path + ".value"
|
return "hwif_in." + path + ".next"
|
||||||
elif isinstance(obj, SignalNode):
|
elif isinstance(obj, SignalNode):
|
||||||
if obj.get_path() in self.out_of_hier_signals:
|
if obj.get_path() in self.out_of_hier_signals:
|
||||||
return obj.inst_name
|
return obj.inst_name
|
||||||
|
|||||||
@@ -30,9 +30,10 @@ class InputStructGenerator_Hier(RDLFlatStructGenerator):
|
|||||||
type_name = self.get_typdef_name(node)
|
type_name = self.get_typdef_name(node)
|
||||||
self.push_struct(type_name, node.inst_name)
|
self.push_struct(type_name, node.inst_name)
|
||||||
|
|
||||||
# Provide input to field's value if it is writable by hw
|
# Provide input to field's next value if it is writable by hw, and it
|
||||||
if node.is_hw_writable:
|
# was not overridden by the 'next' property
|
||||||
self.add_member("value", node.width)
|
if node.is_hw_writable and node.get_property('next') is None:
|
||||||
|
self.add_member("next", node.width)
|
||||||
|
|
||||||
# Generate implied inputs
|
# Generate implied inputs
|
||||||
for prop_name in ["we", "wel", "swwe", "swwel", "hwclr", "hwset"]:
|
for prop_name in ["we", "wel", "swwe", "swwel", "hwclr", "hwset"]:
|
||||||
|
|||||||
@@ -15,13 +15,13 @@
|
|||||||
cpuif.assert_read('h0, 11);
|
cpuif.assert_read('h0, 11);
|
||||||
assert(cb.hwif_out.r1.f.value == 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);
|
cpuif.assert_read('h0, 11);
|
||||||
assert(cb.hwif_out.r1.f.value == 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.hwif_in.r1.f.we <= 1;
|
||||||
@cb;
|
@cb;
|
||||||
cb.hwif_in.r1.f.value <= 0;
|
cb.hwif_in.r1.f.next <= 0;
|
||||||
cb.hwif_in.r1.f.we <= 0;
|
cb.hwif_in.r1.f.we <= 0;
|
||||||
cpuif.assert_read('h0, 12);
|
cpuif.assert_read('h0, 12);
|
||||||
assert(cb.hwif_out.r1.f.value == 12);
|
assert(cb.hwif_out.r1.f.value == 12);
|
||||||
@@ -42,12 +42,12 @@
|
|||||||
cpuif.write('h2, 31);
|
cpuif.write('h2, 31);
|
||||||
cpuif.assert_read('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);
|
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.hwif_in.r3.f.wel <= 0;
|
||||||
@cb;
|
@cb;
|
||||||
cb.hwif_in.r3.f.value <= 0;
|
cb.hwif_in.r3.f.next <= 0;
|
||||||
cb.hwif_in.r3.f.wel <= 1;
|
cb.hwif_in.r3.f.wel <= 1;
|
||||||
cpuif.assert_read('h2, 32);
|
cpuif.assert_read('h2, 32);
|
||||||
|
|
||||||
@@ -66,13 +66,13 @@
|
|||||||
cpuif.assert_read('h4, 50);
|
cpuif.assert_read('h4, 50);
|
||||||
assert(cb.hwif_out.r5.f.value == 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);
|
cpuif.assert_read('h4, 50);
|
||||||
assert(cb.hwif_out.r5.f.value == 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.hwif_in.r5.f.we <= 1;
|
||||||
@cb;
|
@cb;
|
||||||
cb.hwif_in.r5.f.value <= 0;
|
cb.hwif_in.r5.f.next <= 0;
|
||||||
cb.hwif_in.r5.f.we <= 0;
|
cb.hwif_in.r5.f.we <= 0;
|
||||||
cpuif.assert_read('h4, 52);
|
cpuif.assert_read('h4, 52);
|
||||||
assert(cb.hwif_out.r5.f.value == 52);
|
assert(cb.hwif_out.r5.f.value == 52);
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
|
|
||||||
// r7 - sw=r; hw=w; // Wire/Bus - hardware assigns value
|
// r7 - sw=r; hw=w; // Wire/Bus - hardware assigns value
|
||||||
cpuif.assert_read('h6, 0);
|
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.assert_read('h6, 70);
|
||||||
cpuif.write('h6, 71);
|
cpuif.write('h6, 71);
|
||||||
cpuif.assert_read('h6, 70);
|
cpuif.assert_read('h6, 70);
|
||||||
@@ -108,13 +108,13 @@
|
|||||||
cpuif.assert_read('h8, 0);
|
cpuif.assert_read('h8, 0);
|
||||||
assert(cb.hwif_out.r9.f.value == 91);
|
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);
|
cpuif.assert_read('h8, 0);
|
||||||
assert(cb.hwif_out.r9.f.value == 91);
|
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.hwif_in.r9.f.we <= 1;
|
||||||
@cb;
|
@cb;
|
||||||
cb.hwif_in.r9.f.value <= 0;
|
cb.hwif_in.r9.f.next <= 0;
|
||||||
cb.hwif_in.r9.f.we <= 0;
|
cb.hwif_in.r9.f.we <= 0;
|
||||||
cpuif.assert_read('h8, 0);
|
cpuif.assert_read('h8, 0);
|
||||||
assert(cb.hwif_out.r9.f.value == 92);
|
assert(cb.hwif_out.r9.f.value == 92);
|
||||||
|
|||||||
@@ -60,4 +60,14 @@ addrmap top {
|
|||||||
} f[7:0] = 0x44;
|
} f[7:0] = 0x44;
|
||||||
} r4;
|
} r4;
|
||||||
r4.f->wel = hw_ctrl.hw_wel;
|
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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
cpuif.write('h0, 'h00_F0);
|
cpuif.write('h0, 'h00_F0);
|
||||||
|
|
||||||
// test hwenable + we
|
// 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.hwif_in.r1.f.we <= '1;
|
||||||
@cb;
|
@cb;
|
||||||
cb.hwif_in.r1.f.we <= '0;
|
cb.hwif_in.r1.f.we <= '0;
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
cpuif.write('h0, 'hF0_00);
|
cpuif.write('h0, 'hF0_00);
|
||||||
|
|
||||||
// test hwmask + we
|
// 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.hwif_in.r2.f.we <= '1;
|
||||||
@cb;
|
@cb;
|
||||||
cb.hwif_in.r2.f.we <= '0;
|
cb.hwif_in.r2.f.we <= '0;
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
cpuif.assert_read('hC, 'h0F);
|
cpuif.assert_read('hC, 'h0F);
|
||||||
|
|
||||||
// test hwenable + we via reference
|
// test hwenable + we via reference
|
||||||
cb.hwif_in.r3.f.value <= 'hAA;
|
cb.hwif_in.r3.f.next <= 'hAA;
|
||||||
// toggle hwenable = 0F, we=1
|
// toggle hwenable = 0F, we=1
|
||||||
cpuif.write('h0, 'h4_00_0F);
|
cpuif.write('h0, 'h4_00_0F);
|
||||||
cpuif.write('h0, 'h0_00_00);
|
cpuif.write('h0, 'h0_00_00);
|
||||||
@@ -80,15 +80,26 @@
|
|||||||
|
|
||||||
//---------------------------------
|
//---------------------------------
|
||||||
// test wel via reference
|
// test wel via reference
|
||||||
cb.hwif_in.r4.f.value <= 'hBB;
|
cb.hwif_in.r4.f.next <= 'hBB;
|
||||||
// toggle wel
|
// toggle wel
|
||||||
cpuif.write('h0, 'h10_00_00);
|
cpuif.write('h0, 'h10_00_00);
|
||||||
cpuif.write('h0, 'h00_00_00);
|
cpuif.write('h0, 'h00_00_00);
|
||||||
cpuif.assert_read('h10, 'hBB);
|
cpuif.assert_read('h10, 'hBB);
|
||||||
|
|
||||||
cb.hwif_in.r4.f.value <= 'hCC;
|
cb.hwif_in.r4.f.next <= 'hCC;
|
||||||
// toggle wel
|
// toggle wel
|
||||||
cpuif.write('h0, 'h10_00_00);
|
cpuif.write('h0, 'h10_00_00);
|
||||||
cpuif.write('h0, 'h00_00_00);
|
cpuif.write('h0, 'h00_00_00);
|
||||||
cpuif.assert_read('h10, 'hCC);
|
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 %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
// Verify that hwif gets sampled at the same cycle as swacc strobe
|
// Verify that hwif gets sampled at the same cycle as swacc strobe
|
||||||
counter = 'h10;
|
counter = 'h10;
|
||||||
cb.hwif_in.r1.f.value <= counter;
|
cb.hwif_in.r1.f.next <= counter;
|
||||||
@cb;
|
@cb;
|
||||||
event_count = 0;
|
event_count = 0;
|
||||||
fork
|
fork
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
##0;
|
##0;
|
||||||
forever begin
|
forever begin
|
||||||
counter++;
|
counter++;
|
||||||
cb.hwif_in.r1.f.value <= counter;
|
cb.hwif_in.r1.f.next <= counter;
|
||||||
@cb;
|
@cb;
|
||||||
if(cb.hwif_out.r1.f.swacc) begin
|
if(cb.hwif_out.r1.f.swacc) begin
|
||||||
latched_data = counter;
|
latched_data = counter;
|
||||||
|
|||||||
Reference in New Issue
Block a user