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
|
||||
|
||||
! 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
|
||||
|
||||
@@ -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
|
||||
^^^^^^^^^^^
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"]:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user