[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-user: Embedded Power Pins



The gschem logic symbols seem to have embedded Vcc and GND connections
(at least the ones that I was looking at). Since I am working on a
board that has 3.3V and 5V logic this is a problem.

I created a script that takes a logic symbol with embedded Vcc and GND
nets and creates (1) a new symbol with the power nets removed and (2)
a new symbol with two power pins. My plan is to place power symbols
(and decoupling caps) for each IC in a separate section of my
schematic.

Since many symbols contain the same pinout for power pins the power
pin symbol is a symlink to a generic symbol. The new symbol without
power pins have a _np suffix. The symbol containing the power pins has
a _pwr suffix.

For example the 7400-1.sym (with Vcc at pin 14, GND at pin 7) would
produce the files ---

  7400-1_np.sym         7400.sym without power pins
  pwr_Vcc_14_GND_7.sym  refdes, power pin, ground pin
  7400-1_pwr.sym        symlink to pwr_Vcc_14_GND_7.sym

I have performed minimal testing on this script. I diffed a couple
of symbols and verified that an _np part and a _pwr part netlisted
correctly.

The safest way to use the script would be to copy all of the symbols to be
converted to a separate directory and to run the script on the copies.
If you encounter problems please send me an email.

The script is below.

(* jcl *)

--
http://www.luciani.org


#!/usr/bin/perl

# Copyright (C) 2006 John C. Luciani Jr.

# This program may be distributed or modified under the terms of
# version 0.2 of the No-Fee Software License published by
# John C. Luciani Jr.

# A copy of the license is at the end of this file.

#####

# For each symbol in the current directory this script creates a new
# symbol without the embedded power connections and a new symbol with
# only the power pins. The symbol without the power pins has an "_np"
# suffix. The symbol containing only the power pins has a "_pwr"
# suffix. Since many symbols contain the same pinout for power pins
# the power pin symbol is a symlink to a generic symbol.

# This script only works for symbols with one power net and one
# ground.  The routine that creates the power pin symbols has
# specifications for only two pins.

use strict;
use warnings;
use Carp;
use IO::File;

# @Power_pins ... each element of this array is an anonymous hash containing
#                 the filename, Vcc pin number, and GND pin number.
# @Net_names .... names of the power nets to remove.
# @Files ........ all of the symbol files in the current directory.

my @Net_names = $#ARGV == -1 ? qw(Vcc GND) : @ARGV;
my @Files = <*.sym>;
my @Power_pins;

# To find the power pins we look for a text line followed by a
# net=NET_NAME line where NET_NAME is an element in the array
# @Net_names

foreach my $filename (@Files) {

    # skip the files that were created by this script.

    next if $filename =~ /_np.sym$/;  # already done
    next if $filename =~ /^pwr/;      # generic power symbol
    next if $filename =~ /_pwr.sym$/; # power symbol symlink
    print "$filename\n";
    @ARGV = ($filename);
    my $np_filename = $filename;
    $np_filename =~ s/\.sym/_np.sym/;
    my %pins; # contains the filename and power pins for the current symbol
    open(OUT, ">$np_filename") || croak "Could not open $np_filename
for output: $!";
    while (<>) {
 	print(OUT), next unless /^\s*T/;

 	# Found a text line.

 	my $text = $_;
 	my $line = <>;
	my $power_net_p;
 	foreach my $net_name (@Net_names) {
 	    next unless $line =~ /^\s*net\s*=\s*$net_name\s*:\s*(\d+)/;
 	    $pins{$net_name} = $1;
	    $power_net_p = 1;
 	    last;
 	}
	print(OUT $text, $line) unless defined $power_net_p;
    }
    close(OUT) || croak "Could not close $np_filename";
    push @Power_pins, { filename => $filename, %pins };
}

# gschem constants --- DO NOT CHANGE THESE

use constant NORMAL_PIN => 0;
use constant FIRST_POINT_ACTIVE => 0;
use constant VISIBLE => 1;
use constant SHOW_VALUE => 1;
use constant ANCHOR_SW => 0;
use constant ANCHOR_NW => 2;
use constant ANCHOR_N  => 5;
use constant ANCHOR_S  => 3;
use constant ANCHOR_SE => 6;
use constant ANCHOR_NE => 8;
use constant TEXT_FORMAT => "T %i %i %i %i %i %i %i %i %i\n%s\n";


# Change these constants and values in the %Pin_param
# hash to change the power symbol appearance.

use constant REFDES_X2_OFFSET => -25;
use constant REFDES_Y2_OFFSET => 25;
use constant REFDES_ALIGN => ANCHOR_SE;
use constant TEXT_COLOR => 5;
use constant TEXT_SIZE  => 6;
use constant PIN_LENGTH => 100;
use constant PIN_SPACING => 300;
use constant PIN_COLOR   => 5;
use constant SYM_OFFSET => 100;

# hash key 0 corresponds to the first power net.
# hash key 1 corresponds to the second power net

my %Pin_param = (0 => { pin_label_align      => ANCHOR_N,
			pin_label_x2_offset  => 0,
			pin_label_y2_offset  => -25,
			pin_number_align     => ANCHOR_SW,
			pin_number_x2_offset => 25,
			pin_number_y2_offset => 25,
			x1 => 0 + SYM_OFFSET,
			y1 => 2 * PIN_LENGTH + PIN_SPACING + SYM_OFFSET,
			x2 => 0 + SYM_OFFSET,
			y2 => PIN_LENGTH + PIN_SPACING + SYM_OFFSET},
		 1 => { pin_label_align      => ANCHOR_S,
			pin_label_x2_offset  => 0,
			pin_label_y2_offset  => 25,
			pin_number_align     => ANCHOR_NW,
			pin_number_x2_offset => 25,
			pin_number_y2_offset => -25,
			x1 => 0 + SYM_OFFSET,
			y1 => 0 + SYM_OFFSET,
			x2 => 0 + SYM_OFFSET,
			y2 => PIN_LENGTH + SYM_OFFSET});


# Each element in @Power_pins is an anonymous hash containing the
# power pin nets and the filename they came from.

# $pin_ref is a reference to the hash.

foreach my $pin_ref (@Power_pins) {

    # Skip parts that do not have an entry for both parts.

    my $missing_pwr_nets_p;
    foreach my $net_name (@Net_names) {
	next if defined $pin_ref->{$net_name};
	printf("   file %s is missing the $net_name net\n", $pin_ref->{filename});
	$missing_pwr_nets_p = 1;
    }
    next if $missing_pwr_nets_p;
    my $symbol_name = sprintf("pwr_%s_%i_%s_%i.sym",
			      map { $_ => $pin_ref->{$_} } @Net_names);
    if (-e $symbol_name) {
	# Do not overwrite an existing power symbol
    } else {
	my $fh = IO::File->new(">$symbol_name")
	           || croak "Could not open $symbol_name for output: $!";
	$fh -> print("v 20031231 1\n");
	foreach my $i (0..1) {
	
	    # output the pins

	    my $net_name = $Net_names[$i];
	    &pin(fh => $fh,
		 pin_number => $pin_ref->{ $net_name },
		 pin_name   => $net_name,
		 % { $Pin_param{$i} });
	}

	# output the refdes

	$fh -> printf(TEXT_FORMAT,
		      REFDES_X2_OFFSET + $Pin_param{0}{x2},
		      REFDES_Y2_OFFSET + $Pin_param{0}{y2},
		      TEXT_COLOR,
		      TEXT_SIZE,
		      VISIBLE,
		      SHOW_VALUE,
		      0,
		      REFDES_ALIGN,
		      1,
		      'refdes=U?');

	$fh -> close() || croak "Could not close $symbol_name: $!";
    }
    my $symlink_name = $pin_ref->{filename};
    $symlink_name =~ s/\.sym$/_pwr.sym/;
    system("rm $symlink_name") if -l $symlink_name;
    system("ln -s $symbol_name $symlink_name");
}

sub pin  {
    my %arg = @_;
    $arg{fh} -> printf("P %i %i %i %i %i %i %i\n",
		       $arg{x1}, $arg{y1}, $arg{x2}, $arg{y2},
		       PIN_COLOR, NORMAL_PIN, FIRST_POINT_ACTIVE);
    $arg{fh} -> printf("{\n");
    $arg{fh} -> printf(TEXT_FORMAT,
		       $arg{pin_label_x2_offset} + $arg{x2},
		       $arg{pin_label_y2_offset} + $arg{y2},
		       TEXT_COLOR,
		       TEXT_SIZE,
		       VISIBLE,
		       SHOW_VALUE,
		       0,
		       $arg{pin_label_align},
		       1,
		       "pinlabel=$arg{pin_name}");
    $arg{fh} -> printf(TEXT_FORMAT,
		       $arg{pin_number_x2_offset} + $arg{x2},
		       $arg{pin_number_y2_offset} + $arg{y2},
		       TEXT_COLOR,
		       TEXT_SIZE,
		       VISIBLE,
		       SHOW_VALUE,
		       0,
		       $arg{pin_number_align},
		       1,
		       "pinnumber=$arg{pin_number}");
    $arg{fh} -> printf("}\n");
}

# Style (adapted from the Perl Cookbook, First Edition, Recipe 12.4)

# 1. Names of functions and local variables are all lowercase.
# 2. The program's persistent variables (either file lexicals
#    or package globals) are capitalized.
# 3. Identifiers with multiple words have each of these
#    separated by an underscore for readability.
# 4. Constants are all uppercase.
# 5. If the arrow operator (->) is followed by either a
#    method name or a variable containing a method name then
#    there is a space before and after the operator.


##### No-Fee Software License Version 0.2

#### Intent

### The intent of this license is to allow for distribution of this
### software without fee. Usage of this software other than
### distribution, is unrestricted.

#### License

### Permission is granted to make and distribute verbatim copies of
### this software provided that (1) no fee is charged and (2) the
### copyright notice and license statement are preserved on all copies.

### Permission is granted to make and distribute modified versions of
### this software provided that the entire resulting derived work is
### distributed (1) without fee and (2) with a license identical to
### this one.

### This software is provided by the author "AS IS" and any express or
### implied warranties, including, but not limited to, the implied
### warranties of merchantability and fitness for a particular purpose
### are disclaimed. In no event shall the author be liable for any
### direct, indirect, incidental, special, exemplary, or consequential
### damages (including, but not limited to, procurement of substitute
### goods or services; loss of use, data, or profits; or business
### interruption) however caused and on any theory of liability,
### whether in contract, strict liability, or tort (including
### negligence or otherwise) arising in any way out of the use of this
### software, even if advised of the possibility of such damage.