|
@@ -10,9 +10,17 @@ use File::Spec;
|
|
|
# Variables from configuration file
|
|
|
our $iodev_addr_bits;
|
|
|
our $iodev_addr_shift;
|
|
|
+our $xdev_addr_bits;
|
|
|
+our $xdev_addr_shift;
|
|
|
our @sysirqs;
|
|
|
our @iodevs;
|
|
|
|
|
|
+sub base($$$) {
|
|
|
+ my($num,$bits,$shift) = @_;
|
|
|
+
|
|
|
+ my $v = ($num | (~0 << $bits)) << $shift;
|
|
|
+ return $v & 0xffffffff;
|
|
|
+}
|
|
|
|
|
|
sub generate_h($) {
|
|
|
my($out) = @_;
|
|
@@ -23,8 +31,9 @@ sub generate_h($) {
|
|
|
printf $out "#define IODEV_ADDR_BITS %d\n", $iodev_addr_bits;
|
|
|
printf $out "#define IODEV_ADDR_SHIFT %d\n", $iodev_addr_shift;
|
|
|
|
|
|
- my $ndev = 0;
|
|
|
- my $nirq = 0;
|
|
|
+ my $ndev = 0;
|
|
|
+ my $nxdev = 0;
|
|
|
+ my $nirq = 0;
|
|
|
|
|
|
print $out "\n";
|
|
|
|
|
@@ -41,15 +50,25 @@ sub generate_h($) {
|
|
|
next unless ($dcount);
|
|
|
|
|
|
my $name = uc($dev->{-name});
|
|
|
-
|
|
|
- printf $out "\n#define %s_DEV %d\n", $name, $ndev;
|
|
|
+ my $xdev = $dev->{-xdev};
|
|
|
+
|
|
|
+ if ($xdev) {
|
|
|
+ printf $out "\n#define %s_XDEV %d\n", $name, $nxdev;
|
|
|
+ printf $out "#define %s_BASE 0x%08x\n", $name,
|
|
|
+ base($nxdev, $xdev_addr_bits, $xdev_addr_shift);
|
|
|
+ } else {
|
|
|
+ printf $out "\n#define %s_DEV %d\n", $name, $ndev;
|
|
|
+ printf $out "#define %s_BASE 0x%08x\n", $name,
|
|
|
+ base($ndev, $iodev_addr_bits, $iodev_addr_shift);
|
|
|
+ }
|
|
|
printf $out "#define %s_DEV_COUNT %d\n", $name, $dcount;
|
|
|
if ($icount) {
|
|
|
printf $out "#define %s_IRQ %d\n", $name, $nirq;
|
|
|
}
|
|
|
|
|
|
- $ndev += $dcount;
|
|
|
- $nirq += $dcount * $icount;
|
|
|
+ $ndev += $xdev ? 0 : $dcount;
|
|
|
+ $nxdev += $xdev ? $dcount : 0;
|
|
|
+ $nirq += $dcount * $icount;
|
|
|
}
|
|
|
|
|
|
printf $out "\n#define IRQ_VECTORS %d\n", $nirq;
|
|
@@ -111,17 +130,23 @@ sub generate_verilog($)
|
|
|
my($out) = @_;
|
|
|
|
|
|
my $ndev = 0;
|
|
|
+ my $nxdev = 0;
|
|
|
my $nirq = scalar(@sysirqs);
|
|
|
my $irq_edge = 0;
|
|
|
|
|
|
my @imux = ();
|
|
|
+ my @xmux = ();
|
|
|
my @wait = ();
|
|
|
my @valid = ();
|
|
|
my @irqs = ();
|
|
|
|
|
|
- print $out "\twire [31:0] iodev_rdata;\n";
|
|
|
- printf $out "\twire [%d:0] iodev_valid = iodev_mem_valid << cpu_mem_addr[%d:%d];\n",
|
|
|
- (1 << $iodev_addr_bits)-1,
|
|
|
+ print $out "\treg [31:0] nxdev_rdata;\n";
|
|
|
+ print $out "\treg [31:0] iodev_rdata;\n";
|
|
|
+ printf $out "\twire [%d:0] xdev_valid = iodev_mem_valid << cpu_mem_addr[%d:%d];\n",
|
|
|
+ (1 << $xdev_addr_bits)-1,
|
|
|
+ $xdev_addr_shift+$xdev_addr_bits-1, $xdev_addr_shift;
|
|
|
+ printf $out "\twire [%d:0] iodev_valid = xdev_valid[%d] << cpu_mem_addr[%d:%d];\n",
|
|
|
+ (1 << $iodev_addr_bits)-1, (1 << $xdev_addr_bits)-1,
|
|
|
$iodev_addr_shift+$iodev_addr_bits-1, $iodev_addr_shift;
|
|
|
|
|
|
print $out "\n";
|
|
@@ -129,6 +154,7 @@ sub generate_verilog($)
|
|
|
foreach my $dev (@iodevs) {
|
|
|
my $dcount = $dev->{-count};
|
|
|
my $irq = $dev->{-irq};
|
|
|
+ my $xdev = $dev->{-xdev};
|
|
|
|
|
|
$dcount = 1 unless (defined($dcount));
|
|
|
|
|
@@ -144,8 +170,13 @@ sub generate_verilog($)
|
|
|
length($irq)-1, $name, $didx;
|
|
|
}
|
|
|
|
|
|
- printf $out "\twire [%2d:0] iodev_valid_%s = iodev_valid[%d:%d];\n",
|
|
|
- $dcount-1, $name, $ndev+$dcount-1, $ndev;
|
|
|
+ if ($xdev) {
|
|
|
+ printf $out "\twire [%2d:0] iodev_valid_%s = xdev_valid[%d:%d];\n",
|
|
|
+ $dcount-1, $name, $nxdev+$dcount-1, $nxdev;
|
|
|
+ } else {
|
|
|
+ printf $out "\twire [%2d:0] iodev_valid_%s = iodev_valid[%d:%d];\n",
|
|
|
+ $dcount-1, $name, $ndev+$dcount-1, $ndev;
|
|
|
+ }
|
|
|
|
|
|
printf $out "\ttri1 [%2d:0] iodev_wait_n_%s;\n", $dcount-1, $name;
|
|
|
push(@wait, "(&iodev_wait_n_$name)");
|
|
@@ -155,7 +186,11 @@ sub generate_verilog($)
|
|
|
for (my $d = 0; $d < $dcount; $d++) {
|
|
|
my $dsuf = ($dcount > 1) ? "[$d]" : '';
|
|
|
|
|
|
- push(@imux, "iodev_rdata_$name$dsuf");
|
|
|
+ if ($xdev) {
|
|
|
+ push(@xmux, "iodev_rdata_$name$dsuf");
|
|
|
+ } else {
|
|
|
+ push(@imux, "iodev_rdata_$name$dsuf");
|
|
|
+ }
|
|
|
for (my $i = 0; $i < length($irq); $i++) {
|
|
|
my $isuf = "[$i]";
|
|
|
my $type = substr($irq,$i,1);
|
|
@@ -168,19 +203,34 @@ sub generate_verilog($)
|
|
|
|
|
|
$nirq++;
|
|
|
}
|
|
|
- $ndev++;
|
|
|
+ if ($xdev) {
|
|
|
+ $nxdev++;
|
|
|
+ } else {
|
|
|
+ $ndev++;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
print $out "\t// I/O input MUX\n";
|
|
|
- print $out "\talways \@(\*)\n";
|
|
|
+ print $out "\talways_comb\n";
|
|
|
printf $out "\t\tcase (cpu_mem_addr[%d:%d])\n",
|
|
|
+ $xdev_addr_shift+$xdev_addr_bits-1, $xdev_addr_shift;
|
|
|
+ my $nxdev = 0;
|
|
|
+ foreach my $dev (@xmux) {
|
|
|
+ printf $out "\t\t\t%d'd%d:\t iodev_rdata = %s;\n",
|
|
|
+ $xdev_addr_bits, $nxdev++, $dev;
|
|
|
+ }
|
|
|
+ printf $out "\t\t\t%d'd%d:\n",
|
|
|
+ $xdev_addr_bits, (1 << $xdev_addr_bits)-1;
|
|
|
+ printf $out "\t\t\tcase (cpu_mem_addr[%d:%d])\n",
|
|
|
$iodev_addr_shift+$iodev_addr_bits-1, $iodev_addr_shift;
|
|
|
my $ndev = 0;
|
|
|
foreach my $dev (@imux) {
|
|
|
- printf $out "\t\t\t%d'd%d:\t iodev_rdata = %s;\n",
|
|
|
+ printf $out "\t\t\t\t%d'd%d:\t iodev_rdata = %s;\n",
|
|
|
$iodev_addr_bits, $ndev++, $dev;
|
|
|
}
|
|
|
+ print $out "\t\t\t\tdefault: iodev_rdata = 32'hffffffff;\n";
|
|
|
+ print $out "\t\t\tendcase\n";
|
|
|
print $out "\t\t\tdefault: iodev_rdata = 32'hffffffff;\n";
|
|
|
print $out "\t\tendcase\n";
|
|
|
|