Initial commit
* Bare skeleton implementation of everything * Testbench builds with Verilator * Test runs
This commit is contained in:
336
scripts/gen_axi_intf.pl
Executable file
336
scripts/gen_axi_intf.pl
Executable file
@@ -0,0 +1,336 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use Data::Dumper;
|
||||
|
||||
my $app = {};
|
||||
|
||||
get_axi_intf_data($app);
|
||||
augment_intf_data($app);
|
||||
#print Dumper($app->{'intf_data'}); # Debugging output
|
||||
|
||||
gen_intf($app);
|
||||
|
||||
# -----------------
|
||||
# Subroutines
|
||||
# -----------------
|
||||
sub gen_intf {
|
||||
my ($app) = @_;
|
||||
|
||||
print "// Generated AXI Interface\n";
|
||||
print "// This file is automatically generated by $0\n";
|
||||
print "// Do not edit this file directly.\n";
|
||||
print "//\n";
|
||||
print "// Interface Name: $app->{'intf_data'}->{'name'}\n";
|
||||
print "interface axi_intf #(\n";
|
||||
|
||||
my @plines = get_param_lines($app);
|
||||
print join(",\n", @plines);
|
||||
print "\n)\n";
|
||||
my @eplines = get_ext_ports_lines($app);
|
||||
print "\n(\n";
|
||||
print join(",\n", @eplines);
|
||||
print "\n);\n";
|
||||
|
||||
show_interface($app);
|
||||
|
||||
show_modport($app, 'Manager');
|
||||
show_modport($app, 'Subordinate');
|
||||
|
||||
print "endinterface // axi_intf\n";
|
||||
}
|
||||
|
||||
# -----------------
|
||||
sub get_param_lines {
|
||||
my ($app) = @_;
|
||||
my @plines;
|
||||
|
||||
foreach my $p (sort { $a cmp $b } keys %{$app->{'intf_data'}->{'params'}}) {
|
||||
my $param_value = $app->{'intf_data'}->{'params'}->{$p}->{'d'};
|
||||
push(@plines, sprintf(" parameter %$app->{'intf_data'}->{'info'}->{'param_width'}s = %d",
|
||||
$p, $param_value));
|
||||
}
|
||||
|
||||
return @plines;
|
||||
}
|
||||
|
||||
# -----------------
|
||||
sub get_ext_ports_lines {
|
||||
my ($app) = @_;
|
||||
my @eplines;
|
||||
|
||||
foreach my $p (sort { $a cmp $b } @{$app->{'intf_data'}->{'ext_sigs'}}) {
|
||||
push(@eplines, sprintf(" input %s",
|
||||
$p->{'n'}));
|
||||
}
|
||||
|
||||
return @eplines;
|
||||
}
|
||||
|
||||
# -----------------
|
||||
sub show_interface {
|
||||
my ($app) = @_;
|
||||
|
||||
foreach my $section (@{$app->{'intf_data'}->{'sections'}}) {
|
||||
print "\n";
|
||||
print " // $section->{'name'}\n";
|
||||
|
||||
# Display signals
|
||||
foreach my $signal (@{$section->{'signals'}}) {
|
||||
if ($signal->{'s'} eq 'External') {
|
||||
printf " // External signal: %-$app->{'intf_data'}->{'info'}->{'sig_width'}s // $signal->{'d'} [$signal->{'s'}]\n",
|
||||
"$signal->{'n'};";
|
||||
} else {
|
||||
printf " logic %$app->{'intf_data'}->{'info'}->{'dim_width'}s %-$app->{'intf_data'}->{'info'}->{'sig_width'}s // $signal->{'d'} [$signal->{'s'}]\n",
|
||||
get_dimension($app, $signal->{'w'}), "$signal->{'n'};";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# -----------------
|
||||
sub show_modport{
|
||||
my ($app, $role) = @_;
|
||||
my $last = 0;
|
||||
|
||||
print "\n";
|
||||
print " // Modport for $role role\n";
|
||||
print " modport " . uc($role) . " (\n";
|
||||
|
||||
my $num_sections = scalar @{$app->{'intf_data'}->{'sections'}};
|
||||
my $section_count = 0;
|
||||
foreach my $section (@{$app->{'intf_data'}->{'sections'}}) {
|
||||
print "\n";
|
||||
print " // $section->{'name'}\n";
|
||||
|
||||
$section_count++;
|
||||
|
||||
# Display signals
|
||||
my $num_signals = scalar @{$section->{'signals'}};
|
||||
my $signal_count = 0;
|
||||
foreach my $signal (@{$section->{'signals'}}) {
|
||||
# When role is Manager, signals with 'Manager' source are output, others are input
|
||||
# When role is Subordinate, signals with 'Subordinate' source are output, others are input
|
||||
my $direction = ($role eq 'Global') ? 'input' : ($role eq $signal->{'s'}) ? 'output' : 'input';
|
||||
|
||||
$signal_count++;
|
||||
|
||||
$last = 1 if ($num_signals == $signal_count && $num_sections == $section_count);
|
||||
|
||||
printf " %-8s $signal->{'n'}" . (($last == 1) ? "" : ","). "\n", $direction;
|
||||
}
|
||||
}
|
||||
print " );\n";
|
||||
}
|
||||
|
||||
# -----------------
|
||||
sub augment_intf_data {
|
||||
my ($app) = @_;
|
||||
|
||||
# Pretty print widths
|
||||
$app->{'intf_data'}->{'info'}->{'param_width'} = 0;
|
||||
$app->{'intf_data'}->{'info'}->{'dim_width'} = 0;
|
||||
$app->{'intf_data'}->{'info'}->{'sig_width'} = 0;
|
||||
|
||||
# Capture parameters from signals
|
||||
$app->{'intf_data'}->{'params'} = {};
|
||||
# Capture external signals
|
||||
$app->{'intf_data'}->{'ext_sigs'} = [];
|
||||
foreach my $section (@{$app->{'intf_data'}->{'sections'}}) {
|
||||
foreach my $signal (@{$section->{'signals'}}) {
|
||||
my $width = $signal->{'w'};
|
||||
if ($width !~ /^\d+$/) {
|
||||
unless (exists $app->{'intf_data'}->{'params'}->{$width}) {
|
||||
$app->{'intf_data'}->{'params'}->{$width} = {
|
||||
'd' => 1, # Default value for the parameter
|
||||
};
|
||||
$app->{'intf_data'}->{'info'}->{'param_width'} = length($width)
|
||||
if (length($width) > $app->{'intf_data'}->{'info'}->{'param_width'});
|
||||
}
|
||||
}
|
||||
if ($signal->{'s'} eq 'External') {
|
||||
push(@{$app->{'intf_data'}->{'ext_sigs'}}, $signal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Find the maximum width of the parameters
|
||||
foreach my $section (@{$app->{'intf_data'}->{'sections'}}) {
|
||||
|
||||
foreach my $signal (@{$section->{'signals'}}) {
|
||||
$app->{'intf_data'}->{'info'}->{'dim_width'} = length(get_dimension($app, $signal->{'w'}))
|
||||
if (length(get_dimension($app, $signal->{'w'})) > $app->{'intf_data'}->{'info'}->{'dim_width'});
|
||||
$app->{'intf_data'}->{'info'}->{'sig_width'} = length($signal->{'n'})
|
||||
if (length($signal->{'n'}) > $app->{'intf_data'}->{'info'}->{'sig_width'});
|
||||
}
|
||||
$app->{'intf_data'}->{'info'}->{'sig_width'} += 1; # Account for the semi-colon
|
||||
}
|
||||
}
|
||||
|
||||
# -----------------
|
||||
sub get_dimension {
|
||||
my ($app, $width) = @_;
|
||||
|
||||
if ($width =~ /^\d+$/) {
|
||||
if ($width == 1) {
|
||||
return ""; # Single bit width
|
||||
} else {
|
||||
return "[" . ($width-1) . ":0]"; # Specific width
|
||||
}
|
||||
} else {
|
||||
return "[$width-1:0]"; # Width parameter
|
||||
}
|
||||
}
|
||||
|
||||
# -----------------
|
||||
sub get_axi_intf_data {
|
||||
my ($app) = @_;
|
||||
|
||||
$app->{'intf_data'} = {
|
||||
'name' => "AXI Signal List",
|
||||
'sections' =>
|
||||
[
|
||||
{
|
||||
'name' => 'A2.4.1 Clock and reset signals',
|
||||
'signals' => [
|
||||
{ 'n' => 'ACLK', 'w' => '1', 's' => 'External', 'd' => 'External Global clock signal'},
|
||||
{ 'n' => 'ARESETn', 'w' => '1', 's' => 'External', 'd' => 'External Global reset signal'}
|
||||
]
|
||||
},
|
||||
{
|
||||
'name' => 'A2.1.1 Write request channel',
|
||||
'signals' => [
|
||||
# n: name, w: width, s: source, d: description
|
||||
{'n' =>'AWVALID','w' =>'1','s' =>'Manager','d' =>'Valid indicator' },
|
||||
{'n' =>'AWREADY','w' =>'1','s' =>'Subordinate','d' =>'Ready indicator' },
|
||||
{'n' =>'AWID','w' =>'ID_W_WIDTH','s' =>'Manager','d' =>'Transaction identifier for the write channels' },
|
||||
{'n' =>'AWADDR','w' =>'ADDR_WIDTH','s' =>'Manager','d' =>'Transaction address' },
|
||||
{'n' =>'AWREGION','w' =>'4','s' =>'Manager','d' =>'Region identifier' },
|
||||
{'n' =>'AWLEN','w' =>'8','s' =>'Manager','d' =>'Transaction length' },
|
||||
{'n' =>'AWSIZE','w' =>'3','s' =>'Manager','d' =>'Transaction size' },
|
||||
{'n' =>'AWBURST','w' =>'2','s' =>'Manager','d' =>'Burst attribute' },
|
||||
{'n' =>'AWLOCK','w' =>'1','s' =>'Manager','d' =>'Exclusive access indicator' },
|
||||
{'n' =>'AWCACHE','w' =>'4','s' =>'Manager','d' =>'Memory attributes' },
|
||||
{'n' =>'AWPROT','w' =>'3','s' =>'Manager','d' =>'Access attributes' },
|
||||
{'n' =>'AWNSE','w' =>'1','s' =>'Manager','d' =>'Non-secure extension bit for RME' },
|
||||
{'n' =>'AWQOS','w' =>'4','s' =>'Manager','d' =>'QoS identifier' },
|
||||
{'n' =>'AWUSER','w' =>'USER_REQ_WIDTH','s' =>'Manager','d' =>'User-defined extension to a request' },
|
||||
{'n' =>'AWDOMAIN','w' =>'2','s' =>'Manager','d' =>'Shareability domain of a request' },
|
||||
{'n' =>'AWSNOOP','w' =>'AWSNOOP_WIDTH','s' =>'Manager','d' =>'Write request opcode' },
|
||||
{'n' =>'AWSTASHNID','w' =>'11','s' =>'Manager','d' =>'Stash Node ID' },
|
||||
{'n' =>'AWSTASHNIDEN','w' =>'1','s' =>'Manager','d' =>'Stash Node ID enable' },
|
||||
{'n' =>'AWSTASHLPID','w' =>'5','s' =>'Manager','d' =>'Stash Logical Processor ID' },
|
||||
{'n' =>'AWSTASHLPIDEN','w' =>'1','s' =>'Manager','d' =>'Stash Logical Processor ID enable' },
|
||||
{'n' =>'AWTRACE','w' =>'1','s' =>'Manager','d' =>'Trace signal' },
|
||||
{'n' =>'AWLOOP','w' =>'LOOP_W_WIDTH','s' =>'Manager','d' =>'Loopback signals on the write channels' },
|
||||
{'n' =>'AWMMUVALID','w' =>'1','s' =>'Manager','d' =>'MMU signal qualifier' },
|
||||
{'n' =>'AWMMUSECSID','w' =>'SECSID_WIDTH','s' =>'Manager','d' =>'Secure Stream ID' },
|
||||
{'n' =>'AWMMUSID','w' =>'SID_WIDTH','s' =>'Manager','d' =>'StreamID' },
|
||||
{'n' =>'AWMMUSSIDV','w' =>'1','s' =>'Manager','d' =>'SubstreamID valid' },
|
||||
{'n' =>'AWMMUSSID','w' =>'SSID_WIDTH','s' =>'Manager','d' =>'SubstreamID' },
|
||||
{'n' =>'AWMMUATST','w' =>'1','s' =>'Manager','d' =>'Address translated indicator' },
|
||||
{'n' =>'AWMMUFLOW','w' =>'2','s' =>'Manager','d' =>'SMMU flow type' },
|
||||
{'n' =>'AWPBHA','w' =>'4','s' =>'Manager','d' =>'Page-based Hardware Attributes' },
|
||||
{'n' =>'AWNSAID','w' =>'4','s' =>'Manager','d' =>'Non-secure Access ID' },
|
||||
{'n' =>'AWSUBSYSID','w' =>'SUBSYSID_WIDTH','s' =>'Manager','d' =>'Subsystem ID' },
|
||||
{'n' =>'AWATOP','w' =>'6','s' =>'Manager','d' =>'Atomic transaction opcode' },
|
||||
{'n' =>'AWMPAM','w' =>'MPAM_WIDTH','s' =>'Manager','d' =>'MPAM information with a request' },
|
||||
{'n' =>'AWIDUNQ','w' =>'1','s' =>'Manager','d' =>'Unique ID indicator' },
|
||||
{'n' =>'AWCMO','w' =>'AWCMO_WIDTH','s' =>'Manager','d' =>'CMO type' },
|
||||
{'n' =>'AWTAGOP','w' =>'2','s' =>'Manager','d' =>'Memory Tag operation for write requests' },
|
||||
{'n' =>'AWMECID','w' =>'MECID_WIDTH','s' =>'Manager','d' =>'Memory Encryption Context identifier' },
|
||||
]
|
||||
},
|
||||
{
|
||||
'name' => 'A2.1.1 Write request channel',
|
||||
'signals' => [
|
||||
{ 'n' => 'WVALID', 'w' => '1', 's' => 'Manager', 'd' => 'Valid indicator' },
|
||||
{ 'n' => 'WREADY', 'w' => '1', 's' => 'Subordinate', 'd' => 'Ready indicator' },
|
||||
{ 'n' => 'WDATA', 'w' => 'DATA_WIDTH', 's' => 'Manager', 'd' => 'Write data' },
|
||||
{ 'n' => 'WSTRB', 'w' => 'DATA_WIDTH_DIV_8', 's' => 'Manager', 'd' => 'Write data strobes' },
|
||||
{ 'n' => 'WTAG', 'w' => 'CEIL_DATA_WIDTH_DIV_128_TMS_4', 's' => 'Manager', 'd' => 'Memory Tag' },
|
||||
{ 'n' => 'WTAGUPDATE', 'w' => 'CEIL_DATA_WIDTH_DIV_128', 's' => 'Manager', 'd' => 'Memory Tag update' },
|
||||
{ 'n' => 'WLAST', 'w' => '1', 's' => 'Manager', 'd' => 'Last write data' },
|
||||
{ 'n' => 'WUSER', 'w' => 'USER_DATA_WIDTH', 's' => 'Manager', 'd' => 'User-defined extension to write data' },
|
||||
{ 'n' => 'WPOISON', 'w' => 'CEIL_DATA_WIDTH_DIV_64', 's' => 'Manager', 'd' => 'Poison indicator' },
|
||||
{ 'n' => 'WTRACE', 'w' => '1', 's' => 'Manager', 'd' => 'Trace signal' },
|
||||
]
|
||||
},
|
||||
{
|
||||
'name' => 'A2.1.3 Write response channel',
|
||||
'signals' => [
|
||||
{ 'n' => 'BVALID', 'w' => '1', 's' => 'Subordinate', 'd' => 'Valid indicator' },
|
||||
{ 'n' => 'BREADY', 'w' => '1', 's' => 'Manager', 'd' => 'Ready indicator' },
|
||||
{ 'n' => 'BID', 'w' => 'ID_W_WIDTH', 's' => 'Subordinate', 'd' => 'Transaction identifier for the write channels' },
|
||||
{ 'n' => 'BIDUNQ', 'w' => '1', 's' => 'Subordinate', 'd' => 'Unique ID indicator' },
|
||||
{ 'n' => 'BRESP', 'w' => 'BRESP_WIDTH', 's' => 'Subordinate', 'd' => 'Write response code' },
|
||||
{ 'n' => 'BCOMP', 'w' => '1', 's' => 'Subordinate', 'd' => 'Completion response indicator' },
|
||||
{ 'n' => 'BPERSIST', 'w' => '1', 's' => 'Subordinate', 'd' => "Persist response" },
|
||||
{ 'n' => 'BTAGMATCH', 'w' => '2', 's' => 'Subordinate', 'd' => 'Memory Tag Match response' },
|
||||
{ 'n' => 'BUSER', 'w' => 'USER_RESP_WIDTH', 's' => 'Subordinate', 'd' => 'User-defined extension to a write response' },
|
||||
{ 'n' => 'BTRACE', 'w' => '1', 's' => 'Subordinate', 'd' => 'Trace signal' },
|
||||
{ 'n' => 'BLOOP', 'w' => 'LOOP_W_WIDTH', 's' => 'Subordinate', 'd' => 'Loopback signals on the write channels' },
|
||||
{ 'n' => 'BBUSY', 'w' => '2', 's' => 'Subordinate', 'd' => "Busy indicator" },
|
||||
]
|
||||
},
|
||||
{
|
||||
'name' => 'A2.2.1 Read request channel',
|
||||
'signals' => [
|
||||
{ 'n' => 'ARVALID', 'w' => '1', 's' => 'Manager', 'd' => 'Valid indicator' },
|
||||
{ 'n' => 'ARREADY', 'w' => '1', 's' => 'Subordinate', 'd' => 'Ready indicator' },
|
||||
{ 'n' => 'ARID', 'w' => 'ID_R_WIDTH', 's' => 'Manager', 'd' => 'Transaction identifier for the read channels' },
|
||||
{ 'n' => 'ARADDR', 'w' => 'ADDR_WIDTH', 's' => 'Manager', 'd' => 'Transaction address' },
|
||||
{ 'n' => 'ARREGION', 'w' => '4', 's' => 'Manager', 'd' => 'Region identifier' },
|
||||
{ 'n' => 'ARLEN', 'w' => '8', 's' => 'Manager', 'd'=> "Transaction length" },
|
||||
{ 'n' => 'ARSIZE', 'w' => '3', 's' => 'Manager', 'd' => 'Transaction size' },
|
||||
{ 'n' => 'ARBURST', 'w' => '2', 's' => 'Manager', 'd' => 'Burst attribute' },
|
||||
{ 'n' => 'ARLOCK', 'w' => '1', 's' => 'Manager', 'd' => 'Exclusive access indicator' },
|
||||
{ 'n' => 'ARCACHE', 'w' => '4', 's' => 'Manager', 'd' => 'Memory attributes' },
|
||||
{ 'n' => 'ARPROT', 'w' => '3', 's' => 'Manager', 'd' => 'Access attributes' },
|
||||
{ 'n' => 'ARNSE', 'w' => '1', 's' => 'Manager', 'd' => 'Non-secure extension bit for RME' },
|
||||
{ 'n' => 'ARQOS', 'w' => '4', 's' => 'Manager', 'd' => 'QoS identifier' },
|
||||
{ 'n' => 'ARUSER', 'w' => 'USER_REQ_WIDTH', 's' => 'Manager', 'd' => 'User-defined extension to a request' },
|
||||
{ 'n' => 'ARDOMAIN', 'w' => '2', 's' => 'Manager', 'd' => 'Shareability domain of a request' },
|
||||
{ 'n' => 'ARSNOOP', 'w' => 'ARSNOOP_WIDTH', 's' => 'Manager', 'd' => 'Read request opcode' },
|
||||
{ 'n' => 'ARTRACE', 'w' => '1', 's' => 'Manager', 'd' => 'Trace signal' },
|
||||
{ 'n' => 'ARLOOP', 'w' => 'LOOP_R_WIDTH', 's' => 'Manager', 'd' => 'Loopback signals on the read channels' },
|
||||
{ 'n' => 'ARMMUVALID', 'w' => '1', 's' => 'Manager', 'd' => 'MMU signal qualifier' },
|
||||
{ 'n' => 'ARMMUSECSID', 'w' => 'SECSID_WIDTH', 's' => 'Manager', 'd' => 'Secure Stream ID' },
|
||||
{ 'n' => 'ARMMUSID', 'w' => 'SID_WIDTH', 's' => 'Manager', 'd' => 'StreamID' },
|
||||
{ 'n' => 'ARMMUSSIDV', 'w' => '1', 's' => 'Manager', 'd' => 'SubstreamID valid' },
|
||||
{ 'n' => 'ARMMUSSID', 'w' => 'SSID_WIDTH', 's' => 'Manager', 'd' => 'SubstreamID' },
|
||||
{ 'n' => 'ARMMUATST', 'w' => '1', 's' => 'Manager', 'd' => 'Address translated indicator' },
|
||||
{ 'n' => 'ARMMUFLOW', 'w' => '2', 's' => 'Manager', 'd' => 'SMMU flow type' },
|
||||
{ 'n' => 'ARPBHA', 'w' => '4', 's' => 'Manager', 'd' => 'Page-based Hardware Attributes' },
|
||||
{ 'n' => 'ARNSAID', 'w' => '4', 's' => 'Manager', 'd' => 'Non-secure Access ID' },
|
||||
{ 'n' => 'ARSUBSYSID', 'w' => 'SUBSYSID_WIDTH', 's' => 'Manager', 'd' => 'Subsystem ID' },
|
||||
{ 'n' => 'ARCHUNKEN','w' => '1','s' => 'Manager','d' => 'Read data chunking enable'},
|
||||
{ 'n' => 'ARIDUNQ','w' => '1','s' => 'Manager','d' => 'Unique ID indicator'},
|
||||
{ 'n' => 'ARTAGOP','w' => '2','s' => 'Manager','d' => 'Memory Tag operation for read requests'},
|
||||
{ 'n' => 'ARMECID','w' => 'MECID_WIDTH','s' => 'Manager','d' => 'Memory Encryption Context identifier'},
|
||||
]
|
||||
},
|
||||
{
|
||||
'name' => 'A2.2.2 Read data channel',
|
||||
'signals' => [
|
||||
{ 'n' => 'RVALID', 'w' => '1', 's' => 'Subordinate', 'd' => 'Valid indicator' },
|
||||
{ 'n' => 'RREADY', 'w' => '1', 's' => 'Manager', 'd' => 'Ready indicator' },
|
||||
{ 'n' => 'RID', 'w' => 'ID_R_WIDTH', 's' => 'Subordinate', 'd' => 'Transaction identifier for the read channels' },
|
||||
{ 'n' => 'RIDUNQ', 'w' => '1', 's' => 'Subordinate', 'd' => 'Unique ID indicator' },
|
||||
{ 'n' => 'RDATA', 'w' => 'DATA_WIDTH', 's' => 'Subordinate', 'd' => 'Read data' },
|
||||
{ 'n' => 'RTAG', 'w' => 'CEIL_DATA_WIDTH_DIV_128_TMS_4', 's' => 'Subordinate', 'd' => 'Memory Tag' },
|
||||
{ 'n' => 'RRESP', 'w' => 'RRESP_WIDTH', 's' => 'Subordinate', 'd' => 'Read response' },
|
||||
{ 'n' => 'RLAST', 'w' => '1', 's' => 'Subordinate', 'd' => 'Last read data' },
|
||||
{ 'n' => 'RUSER', 'w' => 'SUM_USER_DATA_WIDTH_USER_RESP_WIDTH', 's' => 'Subordinate', 'd' => 'User-defined extension to read data and response' },
|
||||
{ 'n' => 'RPOISON', 'w' => 'CEIL_DATA_WIDTH_DIV_64', 's' => 'Subordinate', 'd' => 'Poison indicator' },
|
||||
{ 'n' => 'RTRACE', 'w' => '1', 's' => 'Subordinate', 'd' => 'Trace signal' },
|
||||
{ 'n' => 'RLOOP', 'w' => 'LOOP_R_WIDTH', 's' => 'Subordinate', 'd' => 'Loopback signals on the read channels' },
|
||||
{ 'n' => 'RCHUNKV','w' => '1', 's' => 'Subordinate', 'd' => 'Read data chunking valid' },
|
||||
{ 'n' => 'RCHUNKNUM', 'w' => 'RCHUNKNUM_WIDTH', 's' => 'Subordinate', 'd' => 'Read data chunk number' },
|
||||
{ 'n' => 'RCHUNKSTRB', 'w' => 'RCHUNKSTRB_WIDTH', 's' => 'Subordinate', 'd' => 'Read data chunk strobe' },
|
||||
{ 'n' => 'RBUSY', 'w' => '2', 's' => 'Subordinate', 'd' => 'Busy indicator' },
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user