Giter Site home page Giter Site logo

werni2a / openallegroparser Goto Github PK

View Code? Open in Web Editor NEW
40.0 9.0 7.0 175 KB

OpenAllegroParser - FOSS Parser for Cadence Allegro designs.

License: MIT License

CMake 2.76% C++ 91.47% Python 5.78%
reverse-engineering cadence allegro electrical-engineering footprint pcb pcb-designer pcb-layout

openallegroparser's Introduction

OpenAllegroParser

Purpose of this project is to provide a C++17 library for parsing Cadence's Allegro binary file formats. This library can be linked to other software for reading Allegro's binary files and/or exporting them to XML files.

See also the complementary project OpenOrCadParser.

The focus lies on

  • *.brd board database,
  • *.mdd module definition,
  • *.dra drawing,
  • *.psm package symbol,
  • *.ssm shape symbol,
  • *.fsm flash symbol,
  • *.osm format symbol,
  • *.bsm mechanical symbol, and
  • *.pad padstack.

See OrCAD Allegro Files Extension and their Contents or Cadence Allegro file Extensions and what they contain for more information on the file purpose.


Documentation

  • File Formats
    1. *.brd Board Database
    2. *.mdd Module Definition
    3. *.dra Drawing
    4. *.psm Package Symbol
    5. *.ssm Shape Symbol
    6. *.fsm Flash Symbol
    7. *.osm Format Symbol
    8. *.bsm Mechanical Symbol
    9. *.pad Padstack

Current State โ€” April 2022

  • Working on padstack to XML exporter

Build

cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build build

Dependencies


Usage

I tested with some pads created with version 17.4-2019 S019 (3959056) [7/8/2021] which works mostly fine. In case you find pads that do not work - with the specified version - please create an issue and append your *.pad as well as *.pxml files.

Note:

Pad files have some structures with dynamic size where I haven't found a way to calculate those sizes. A workaround to this issue is to brute force all combinations and see when the parser runs without errors. Brute force sounds like a tedious job to do. However, it's quite fast because the amount of possible combinations is relatively low.

Therefore, modify the path to your pad in find_parameter_set.py and run it with python3 find_parameter_set.py. Hopefully there is a parameter set found that works for your file, and you will see an output similar to the following.

---------------------------------------------
------- Found valid Parameter Set -----------
---------------------------------------------

./build/OpenAllegroParser -i simple_example.pad --numUserLayers 5 --bool1

Add the flag -p to the command from above and run it as ./build/OpenAllegroParser -i simple_example.pad --numUserLayers 5 --bool1 -p and you will see a similar output with all the pad's information like the one below. At the beginning a lot of debug output is shown that might be not as interesting for you, as for me. Just scroll down to the more important pad information.

Click to expand

./build/OpenAllegroParser -i simple_example.pad --numUserLayers 5 --bool1 -p

Opening file: "simple_example.pad"
File contains 5020 byte.
File found at 0x00000ed8: simple_example.zip

...

-----------------------------------------------
--------------- File Content ------------------
-----------------------------------------------
PadFile:
  swVersion = pad395907/8/2
  accuracy  = 1
  unit      = mils
  strIdxPadName       = 30 (SIMPLE_EXAMPLE)
  idxUnknown          = 31
  strIdxDrillToolSize = 32 (SIZE_XYZ)
  drillmethod     = ETCH
  holeType        = CIRCLE
  staggeredDrills = 0
  plated          = 1
  not_suppress_nc_internal_pads = 1
  isPolyVia       = 0
  padstackusage   = THRU_PIN
  drill_rows      = 1
  drill_columns   = 1
  lock_layer_span = 1
  offsetX         = 0
  offsetY         = 0
  clearance_columns = 1
  clearance_rows    = 2
  finished_size     = 4
  positivetolerance = 2
  negativetolerance = 1
  width             = 10
  height            = 20
  figure            = CROSS
  characters        = X
  back_drill_figure_width  = 0
  back_drill_figure_height = 0
  back_drill_figure        = NONE
  back_drill_characters    =
  counter_drill_diameter          = 0
  counter_drill_positivetolerance = 0
  counter_drill_negativetolerance = 0
  counterangle         = 0
  genericLayers:
    0: Pad:
      type   = 0
      layer  = 0
      figure = RECTANGLE
      offset = (0.020000;0.030000)
      width  = 0.100000
      height = 0.100000
    1: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    2: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    3: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    4: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    5: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    6: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    7: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    8: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    9: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    10: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    11: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    12: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    13: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    14: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    15: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    16: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    17: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    18: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    19: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    20: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    21: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    22: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
    23: Pad:
      type   = 0
      layer  = 0
      figure = CIRCLE
      offset = (0.020000;0.030000)
      width  = 0.100000
      height = 0.100000
    24: Pad:
      type   = 0
      layer  = 0
      figure = NONE
      offset = (0.000000;0.000000)
      width  = 0.000000
      height = 0.000000
  dateTime1         = Thu Dec 30 20:57:49 2021

  username          = domin
  dateTime2         = Thu Dec 30 20:57:49 2021

  dateTime3         = Thu Dec 30 20:57:49 2021

  dateTime4         = Thu Dec 30 20:57:49 2021

  dateTime5         = Thu Dec 30 20:57:49 2021

  dateTime6         = Thu Dec 30 20:57:49 2021


Closing file: "simple_example.pad"

./build/cli/OpenAllegroParser-cli --help
Allowed options:
  -h [ --help ]         produce help message
  -p [ --print ]        print file content to terminal
  -e [ --extract ]      extract files from within the binary
  -i [ --input ] arg    input file to parse
  -o [ --output ] arg   output path (required iff extract is set)
  -x [ --export ]       export XML file
  -v [ --verbose ]      verbose output
  --export-version arg  Version of padstack_editor.exe used for pxml export
  --bool0               bool0
  --bool1               bool1
  --bool2               bool2
  --int0 arg            int0
  --numUserLayers arg   number of user layers
  --additionalStr2 arg  number of additional strings e.g. symbol names

./build/cli/OpenAllegroParser-cli --input file.pad --extract --output out/
Opening file: file.pad
File contains 4960 byte.
File found at 0x00000abc: file.zip
Extract ZIP file: file.pad/file.zip
Extract from ZIP, 4200 Byte file: out/file.pad/Users/%USERNAME%/AppData/Local/Temp/#Taaaaaa00765.tmp
Closing file: file.pad

Related Projects

kicad-allegro (Rust based Allegro Extract (ASCII) to KiCad Converter and Viewer)


How to Contribute?

There are different ways to help this project forward. Some are

  • provide test files (manually created or automated via SKILL),
  • help reverse engineering/documenting the file format, or
  • implement some unit tests.

In case you don't have access to OrCAD PcbDesigner or Allegro you can get Cadence Allegro Viewer free of charge.


Cadence Terms and Conditions

Terms and Conditions

Terms of Use Agreement

openallegroparser's People

Contributors

werni2a avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openallegroparser's Issues

Unit Test Tracking

Tests that should be implemented into the CI.

Feel free to contribute some test files. A few points to note are listed in the following.

  • If you vary a parameter e.g. an enum try to keep the rest of the parameters the same as for other variations of the same parameter. This simplifies finding the offset, when comparing two files byte-by-byte.

  • Do not use 0.0 or other values that might occur elsewhere in the file for tests. Otherwise we might misinterpret some values and the test does not detect this.

  • Units (enum)

  • Decimal places (unsigned in range [0, 4])

  • Start

    • Padstack usage (enum)
  • Drill

    • Slot
      • Slot type (enum)
      • X size (unsigned)
      • Y size (unsigned)
        • X tolerance
          • +
          • -
        • Y tolerance
          • +
          • -
    • Drill hole
      • Hole type (enum)
      • Finished diameter (unsigned)
      • + Tolerance (unsigned)
      • - Tolerance (unsigned)
      • Drill tool size (string)
      • Non-standard drill (enum)
    • Hole plating
      • Hole/slot plating (enum)
    • Define the drill rows and columns
      • Number of drill rows (unsigned)
      • Number of drill columns (unsigned)
      • Clearance between columns (unsigned)
      • Clearance between rows (unsigned)
      • Drills are staggered (bool)
  • Secondary Drill

    • Backdrill (bool)
      • Diameter (unsigned)
        • Backdrill drill symbol
          • Type of drill figure (enum)
          • Characters (string with <= 3 characters)
          • Drill figure width (unsigned)
          • Drill figure height (unsigned)
    • Counter bore/sink (bool)
      • Bore type (enum)
      • Diameter (unsigned)
      • + Tolerance (unsigned)
      • - Tolerance (unsigned)
      • Depth (unsigned)
  • Drill Symbol

    • Define a drill symbol
      • Type of drill figure (enum)
      • Characters (string with <= 3 characters)
      • Drill figure width (unsigned)
      • Drill figure height (unsigned)
  • Drill Offset

    • Offset from padstack origin to hole
      • Offset x (int)
      • Offset y (int)
  • Design Layers

    • ...
  • Mask Layers

    • ...
  • Options

    • Suppress unconnected internal pads; legacy artwork (bool)
    • Lock layer span (bool)
    • Poly via (bool)

Data format

I used the board linked in the following issue to decode some board informations: OpenBoardView/OpenBoardView#126

In my case, I started with the lowest level of information (e.g. known tracks), thus I hardcoded "known" positions in the file to extract records as I think they might fit. I think for such binary-blobs that's the better approach, as it allows you to expand your knowlege step-wise. If you know how a record look like you can find the first one, and then the index to that record,..

This is just a dump of information I decoded some months ago, hope it helps ๐Ÿ˜ƒ

Main Findings

  • The file is little-endian
    • degrees are stored as 4 byte little endian integers in thousands of degrees (e.g. 180ยฐ = 180000)
    • coordinates are stored as 4 byte little endian integers, first comes x and then y. Sorry, I forgot in which unit they were (but you should find this out using the kaitai file and a board-viewer)
  • I found some general "magic-byte" sequence which seemed to be the same on all files I looked on so far

Kaitai File

meta:
  id: allegro
  title: Allegro board file
  file-extension: brd
  endian: le
  encoding: UTF-8

# Findings (27.04.2021)
# Degree:
#  le 4 byte 180ยฐ = 180000
# Position x|y
#  le 4 byte | le 4 byte
# How found out: search for 180, 1800, 18000 until a high number of matches is found

# those numbers are the same on all allegro files I saw so far:
seq:
  - size: 3
  - id: magic
    contents: [0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00]
  - size: 44
  - id: zeroes1
    contents: [0x00, 0x00, 0x00, 0x00]
  - size: 60
  - id: zeroes2
    contents: [0x00, 0x00, 0x00, 0x00]
  - size: 36
  - id: zeroes3
    contents: [0x00, 0x00, 0x00, 0x00]
  - size: 28
  - id: zeroes4
    contents: [0x00, 0x00, 0x00, 0x00]
  - size: 28
  - id: zeroes5
    contents: [0x00, 0x00, 0x00, 0x00]
  - size: 12
  - id: string1
    type: str
    size: 60
  - size: 24
  - id: zeroes6
    contents: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

instances:
  # file: 77G.MMW.automotive.radar-PCBF-V01-20180115-1520.brd
  # downloaded from https://github.com/OpenBoardView/OpenBoardView/issues/126
  
  # track_segment1: x=-18100 y=219000
  # pos: 0x25f284
  tracks_unknown:
    io: _root._io
    pos: 0x25f130  # hardcoded for now, only valid for this board
    type: tracks

  vias_unknown:
    io: _root._io
    pos: 0x2ea550  # hardcoded for now, only valid for this board
    type: vias

  # pad: 0x0032A990 - -233337 | 149000 | Pin2 | CAN_L

types:
  tracks:
    seq:
      - id: tracks
        type: track_seg
        repeat-expr: 20  # just show some vias to validate record
        repeat: expr

  vias:
    seq:
      - id: vias
        type: via_seg
        repeat-expr: 20  # just show some vias to validate record
        repeat: expr

  test:
    seq:
      - id: type_question_or_layer
        type: u4
      - id: data
        size: 32+4

  # TODO: offsets are wrong at some point
  track_seg:  # track_seg?
    seq:
      - id: type_question_or_layer  # no idea what this is, perhaps we can extract the record type -> size from it?
        type: u4
      - size: 4*4
      - id: width  # TODO: sometimes zero?
        type: s4
      - id: start
        type: point
      - id: end
        type: point


  # TODO: offsets are wrong at some point
  via_seg:
    seq:
      - id: position
        type: point
      - size: 4*5
      - id: rotation
        type: s4
      - size: 4*9

  point:
    seq:
      - id: x
        type: s4
      - id: y
        type: s4

Evaluate Extracta to retrieve information from the binary files

In OrCAD we can export the design into a XML which directly shows us which information is stored in the binary file and probably also how it is stored. Maybe Extracta can do the same for layouts. A short introduction how to use the tool is provided in [1]. Further, [1] states that there is a Linux version of the tool. Can this one be downloaded somewhere or why would Cadence distribute a Linux tool on an Windows machine?

[1] BoardSurfers: Translating Allegro Database to Readable Format Using 'Extracta'

Build instructions reference missing file

I am trying to follow the instructions in README.md. Under the Build header, it asks me to run:

cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake

but I don't see the file vcpkg.cmake in my repository. (And also the command seems to reference the parent folder above the repository.)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.