1;;; gEDA - GPL Electronic Design Automation 2;;; gnetlist - gEDA Netlist 3;;; Copyright (C) 1998-2010 Ales Hvezda 4;;; Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details) 5;;; 6;;; This program is free software; you can redistribute it and/or modify 7;;; it under the terms of the GNU General Public License as published by 8;;; the Free Software Foundation; either version 2 of the License, or 9;;; (at your option) any later version. 10;;; 11;;; This program is distributed in the hope that it will be useful, 12;;; but WITHOUT ANY WARRANTY; without even the implied warranty of 13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14;;; GNU General Public License for more details. 15;;; 16;;; You should have received a copy of the GNU General Public License 17;;; along with this program; if not, write to the Free Software 18;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19;;; MA 02111-1301 USA. 20 21;;; -------------------------------------------------------------------------- 22;;; 23;;; VHDL-AMS netlist backend written by Eduard Moser and Martin Lehmann. 24;;; Build on the VHDL backend from Magnus Danielson 25;;; 26;;; -------------------------------------------------------------------------- 27 28(use-modules (srfi srfi-1)) 29 30;;; =================================================================================== 31;;; TOP LEVEL FUNCTION 32;;; BEGIN 33 34;;; Write structural VAMS representation of the schematic 35 36;;; absolutly toplevel function of gEDA gnelist vams mode. 37;;; its evaluate things like output-file, generate-mode, top-attribs 38;;; and starts the major subroutines. 39 40;; guile didn't like this code: 41;; 42;; (if (string-index output-filename #\.) 43;; (string-rindex output-filename #\.) 44;; ofl) 45;; 46;; as a replacement for line below: 47;; 48;; (lpi (string-rindex output-filename #\. 0 ofl)) 49;; 50;; why? (avh) 51 52(define vams 53 (lambda (output-filename) 54 (let* ((port '()) ;; output-port for architecture 55 (port-entity '()) ;; output-port for entity 56 (ofl (string-length output-filename)) 57 (lpi (string-rindex output-filename #\. 0 ofl)) 58 59 ;; generate correctly architecture name 60 (architecture (vams:change-all-whitespaces-to-underlines 61 (cond 62 ((string=? 63 (gnetlist:get-toplevel-attribute "architecture") 64 "not found") "default_architecture") 65 (else 66 (gnetlist:get-toplevel-attribute "architecture"))))) 67 68 ;; generate correctly entity name 69 (entity (vams:change-all-whitespaces-to-underlines 70 (cond ((string=? 71 (gnetlist:get-toplevel-attribute "entity") 72 "not found") 73 "default_entity") 74 (else (gnetlist:get-toplevel-attribute "entity"))))) 75 76 ;; search all ports of a schematic. for entity generation only. 77 (port-list (vams:generate-port-list (vams:get-uref top-attribs))) 78 79 ;; search all generic of a schematic. for entity generatin only. 80 (generic-list (vams:generate-generic-list top-attribs))) 81 82 83 ;; generate-mode : 1 (default) -> generate a architecture (netlist) of a 84 ;; schematic 85 ;; 2 -> is selected a component then generate 86 ;; a entity of this, else generate 87 ;; a toplevel entity. called from gschem 88 ;; normally. 89 90 (cond ((= generate-mode 1) 91 (begin 92 (display "\ngenerating architecture of current schematic in ") 93 94 ;; generate output-filename, like 95 ;; (<entity>_arc.<output-file-extension>) 96 (set! output-filename 97 (string-append 98 (if (string-index output-filename #\/) 99 (substring output-filename 0 100 (+ (string-rindex 101 output-filename #\/ 0 ofl) 1)) 102 "./") 103 (string-downcase! entity) 104 "_arc" 105 (substring output-filename lpi ofl))) 106 107 (set! port (open-output-file output-filename)) 108 (display output-filename) 109 (newline) 110 (display "-- Structural VAMS generated by gnetlist\n" port) 111 (vams:write-secondary-unit architecture entity port) 112 (close-output-port port))) 113 114 ((= generate-mode 2) 115 (display "\n\ngenerating entity of current schematic in ") 116 117 ;; if one component selected, then generate output-filename 118 ;; (<device of selected component>.vhdl), else 119 ;; <entity>.vhdl 120 (if (not (null? top-attribs)) 121 (set! output-filename 122 (string-append 123 (if (string-index output-filename #\/) 124 (substring output-filename 0 125 (+ (string-rindex 126 output-filename #\/ 0 ofl) 1)) 127 "./") 128 (string-downcase! 129 (get-device (vams:get-uref top-attribs))) 130 ".vhdl")) 131 (set! output-filename 132 (string-append 133 (if (string-index output-filename #\/) 134 (substring output-filename 0 135 (+ (string-rindex 136 output-filename #\/ 0 ofl) 1)) 137 "./") 138 (string-downcase! entity) 139 ".vhdl"))) 140 141 (display output-filename) 142 (newline) 143 (set! port-entity (open-output-file output-filename)) 144 145 ;; decide about the right parameters for entity-declaration 146 (if (not (null? (vams:get-uref top-attribs))) 147 (vams:write-primary-unit (get-device (vams:get-uref top-attribs)) 148 port-list 149 generic-list port-entity) 150 (vams:write-primary-unit entity port-list generic-list 151 port-entity)) 152 153 (close-output-port port-entity)))))) 154 155 156;;; TOP LEVEL FUNCTION 157;;; END 158 159;;; =================================================================================== 160 161;;; 162;;; ENTITY GENERATING PART 163;;; BEGIN 164 165 166;;; Context clause 167;;; 168;;; According to IEEE 1076-1993 11.3: 169;;; 170;;; context_clause := { context_item } 171;;; context_item := library_clause | use_clause 172;;; 173;;; Implementation note: 174;;; Both library and use clauses will be generated, eventually... 175;;; What is missing is the information from gEDA itself, i think. 176 177 178;;; writes some needed library insertions staticly 179;;; not really clever, but a first solution 180 181(define vams:write-context-clause 182 (lambda (p) 183 (display "LIBRARY ieee,disciplines;\n" p) 184 (display "USE ieee.math_real.all;\n" p) 185 (display "USE ieee.math_real.all;\n" p) 186 (display "USE work.electrical_system.all;\n" p) 187 (display "USE work.all;\n" p))) 188 189 190 191;;; Primary unit 192;;; 193;;; According to IEEE 1076-1993 11.1: 194;;; 195;;; primary_unit := 196;;; entity_declaration 197;;; | configuration_declaration 198;;; | package_declaration 199;;; 200;;; Implementation note: 201;;; We assume that gEDA does not generate either a configuration or 202;;; package declaration. Thus, only a entity declaration will be generated. 203;;; 204;;; According to IEEE 1076-1993 1.1: 205;;; 206;;; entity_declaration := 207;;; ENTITY identifier IS 208;;; entity_header 209;;; entity_declarative_part 210;;; [ BEGIN 211;;; entity_statement_part ] 212;;; END [ ENTITY ] [ entity_simple_name ] ; 213;;; 214;;; Implementation note: 215;;; We assume that no entity declarative part and no entity statement part 216;;; is to be produced. Further, it is good custom in VAMS-93 to append 217;;; both the entity keyword as well as the entity simple name to the 218;;; trailer, therefore this is done to keep VAMS compilers happy. 219;;; 220;;; According to IEEE 1076-1993 1.1.1: 221;;; 222;;; entity_header := 223;;; [ formal_generic_clause ] 224;;; [ formal_port_clause ] 225;;; 226;;; Implementation note: 227;;; Initially we will assume that there is no generic clause but that there 228;;; is an port clause. We would very much like to have generic and the port 229;;; clause should be conditional (consider writting a test-bench). 230 231 232;;; this routine managed the complete entity-declaration of a component 233;;; or a schematic. It requires the entity-name, all ports and generics 234;;; of this entity and the output-port. the output-port defines where 235;;; this all should wrote to. 236 237(define vams:write-primary-unit 238 (lambda (entity port-list generic-list p) 239 (begin 240 (vams:write-context-clause p) 241 (display "-- Entity declaration -- \n\n" p) 242 (display "ENTITY " p) 243 (display entity p) 244 (display " IS\n" p) 245 (vams:write-generic-clause generic-list p) 246 (vams:write-port-clause port-list p) 247 (display "END ENTITY " p) 248 (display entity p) 249 (display "; \n\n" p)))) 250 251 252 253;;; GENERIC & PORT Clause 254;;; 255;;; According to IEEE 1076-1993 1.1.1: 256;;; 257;;; entity_header := 258;;; [ formal_generic_clause ] 259;;; [ formal_port_clause ] 260;;; 261;;; generic_clause := 262;;; GENERIC ( generic_list ) ; 263;;; 264;;; port_clause := 265;;; PORT ( port_list ) ; 266;;; 267;;; According to IEEE 1076-1993 1.1.1.2: 268;;; 269;;; port_list := port_interface_list 270;;; 271;;; According to IEEE 1076-1993 4.3.2.1: 272;;; 273;;; interface_list := interface_element { ; interface_element } 274;;; 275;;; interface_element := interface_declaration 276;;; 277;;; According to IEEE 1076-1993 4.3.2: 278;;; 279;;; interface_declaration := 280;;; interface_constant_declaration 281;;; | interface_signal_declaration 282;;; | interface_variable_declaration 283;;; | interface_file_declaration 284;;; 285;;; interface_signal_declaration := 286;;; [ SIGNAL ] identifier_list : [ mode ] subtype_indication [ BUS ] 287;;; [ := static_expression ] 288;;; 289;;; mode := IN | OUT | INOUT | BUFFER | LINKAGE 290;;; 291;;; Implementation note: 292;;; Since the port list must contain signals will only the interface 293;;; signal declaration of the interface declaration be valid. Further, 294;;; we may safely assume that the SIGNAL symbol will not be needed. 295;;; The identifier list is reduced to a signle name entry, mode is set 296;;; to in, out or inout due to which part of the port list it comes from. 297;;; The mode types supported are in, out and inout where as buffer and 298;;; linkage mode is not supported. The subtype indication is currently 299;;; hardwired to standard logic, but should be controlled by attribute. 300;;; There is currently no support for busses and thus is the BUS symbol 301;;; no being applied. Also, there is currently no static expression 302;;; support, this too may be conveyed using attributes. 303 304 305;;; this next two functions are writing the generic-clause 306;;; in the entity declaration 307;;; vams:write-generic-clause requires a list of all generics and 308;;; its values, such like ((power 12.2) (velocity 233.34)) 309 310(define vams:write-generic-clause 311 (lambda (generic-list p) 312 (if (not (null? generic-list)) 313 (begin 314 (display "\t GENERIC (" p) 315 (display "\t" p) 316 (if (= 2 (length (car generic-list))) 317 (begin 318 (display (caar generic-list) p) 319 (display " : REAL := " p) 320 (display (cadar generic-list) p))) 321 (vams:write-generic-list (cdr generic-list) p) 322 (display " );\n" p))))) 323 324(define vams:write-generic-list 325 (lambda (generic-list p) 326 (if (not (null? generic-list)) 327 (begin 328 (display ";\n\t\t\t" p) 329 (if (= 2 (length (car generic-list))) 330 (begin 331 (display (caar generic-list) p) 332 (display " : REAL := " p) 333 (display (cadar generic-list) p))) 334 (vams:write-generic-list (cdr generic-list) p))))) 335 336 337;;; this function writes the port-clause in the entity-declarartion 338;;; It requires a list of ports. ports stand for a list of all 339;;; pin-attributes. 340 341(define vams:write-port-clause 342 (lambda (port-list p) 343 (if (not (null? port-list)) 344 (begin 345 (display "\t PORT (\t" p) 346 (display "\t" p) 347 (if (list? (car port-list)) 348 (begin 349 (display (cadar port-list) p) 350 (display " \t" p) 351 (display (caar port-list) p) 352 (display " \t: " p) 353 (if (equal? (cadar port-list) 'quantity) 354 (display (car (cdddar port-list)) p)) 355 (display " \t" p) 356 (display (caddar port-list) p))) 357 (vams:write-port-list (cdr port-list) p) 358 (display " );\n" p))))) 359 360;;; This little routine writes a single pin on the port-clause. 361;;; It requires a list containing (port_name, port_object, port_type, port_mode) 362;;; such like 363;;; ((heat quantity thermal in) (base terminal electrical unknown) .. ) 364 365(define vams:write-port-list 366 (lambda (port-list p) 367 (if (not (null? port-list)) 368 (begin 369 (display ";\n\t\t\t" p) 370 (if (equal? (length (car port-list)) 4) 371 (begin 372 (display (cadar port-list) p) 373 (display " \t" p) 374 (display (caar port-list) p) 375 (display " \t: " p) 376 (if (equal? (cadar port-list) 'quantity) 377 (display (car (cdddar port-list)) p)) 378 (display " \t" p) 379 (display (caddar port-list) p))) 380 (vams:write-port-list (cdr port-list) p))))) 381 382 383 384;;; ENTITY GENERATING PART 385;;; END 386 387;;; =================================================================================== 388 389;;; ARCHITECTURE GENERATING PART 390;;; BEGIN 391 392 393 394;; Secondary Unit Section 395;; 396 397;;; Architecture Declarative Part 398;;; 399;;; According to IEEE 1076-1993 1.2.1: 400;;; 401;;; architecture_declarative_part := 402;;; { block_declarative_item } 403;;; 404;;; block_declarative_item := 405;;; subprogram_declaration 406;;; | subprogram_body 407;;; | type_declaration 408;;; | subtype_declaration 409;;; | constant_declaration 410;;; | signal_declaration 411;;; | shared_variable_declaration 412;;; | file_declaration 413;;; | alias_declaration 414;;; | component_declaration 415;;; | attribute_declaration 416;;; | attribute_specification 417;;; | configuration_specification 418;;; | disconnection_specification 419;;; | use_clause 420;;; | group_template_declaration 421;;; | group_declaration 422;;; 423;;; Implementation note: 424;;; There is currently no support for programs or procedural handling in 425;;; gEDA, thus will all declarations above involved in thus activites be 426;;; left unused. This applies to subprogram declaration, subprogram body, 427;;; shared variable declaration and file declaration. 428;;; 429;;; Further, there is currently no support for type handling and therefore 430;;; will not the type declaration and subtype declaration be used. 431;;; 432;;; The is currently no support for constants, aliases, configuration 433;;; and groups so the constant declaration, alias declaration, configuration 434;;; specification, group template declaration and group declaration will not 435;;; be used. 436;;; 437;;; The attribute passing from a gEDA netlist into VAMS attributes must 438;;; wait, therefore will the attribute declaration and attribute 439;;; specification not be used. 440;;; 441;;; The disconnection specification will not be used. 442;;; 443;;; The use clause will not be used since we pass the responsibility to the 444;;; primary unit (where it �s not yet supported). 445;;; 446;;; The signal declation will be used to convey signals held within the 447;;; architecture. 448;;; 449;;; The component declaration will be used to convey the declarations of 450;;; any external entity being used within the architecture. 451 452 453;;; toplevel-subfunction for architecture generation. 454;;; requires architecture and entity name and the port, where 455;;; the architecture should wrote to. 456 457(define vams:write-secondary-unit 458 (lambda (architecture entity p) 459 (display "-- Secondary unit\n\n" p) 460 (display "ARCHITECTURE " p) 461 (display architecture p) 462 (display " OF " p) 463 (display entity p) 464 (display " IS\n" p) 465 (vams:write-architecture-declarative-part p) 466 (display "BEGIN\n" p) 467 (vams:write-architecture-statement-part packages p) 468 (display "END ARCHITECTURE " p) 469 (display architecture p) 470 (display ";\n" p))) 471 472 473;;; 474;;; at this time, it only calls the signal declarations 475 476(define vams:write-architecture-declarative-part 477 (lambda (p) 478 (begin 479 ; Due to my taste will the component declarations go first 480 ; XXX - Broken until someday 481 ; (vams:write-component-declarations packages p) 482 ; Then comes the signal declatations 483 (vams:write-signal-declarations p)))) 484 485 486;;; Signal Declaration 487;;; 488;;; According to IEEE 1076-1993 4.3.1.2: 489;;; 490;;; signal_declaration := 491;;; SIGNAL identifier_list : subtype_indication [ signal_kind ] 492;;; [ := expression ] ; 493;;; 494;;; signal_kind := REGISTER | BUS 495;;; 496;;; Implementation note: 497;;; Currently will the identifier list be reduced to a single entry. 498;;; There is no support for either register or bus type of signal kind. 499;;; Further, no default expression is being supported. 500;;; The subtype indication is hardwired to Std_Logic. 501 502 503;;; the really signal-declaration-writing function 504;;; it's something more complex, because it's checking all signals 505;;; for consistence. it only needs the output-port as parameter. 506 507(define vams:write-signal-declarations 508 (lambda (p) 509 (begin 510 (for-each 511 (lambda (net) 512 (let*((connlist (gnetlist:get-all-connections net)) 513 (port_object (vams:net-consistence "port_object" connlist)) 514 (port_type (vams:net-consistence "port_type" connlist)) 515 ;;(if (equal? port_object "quantity") 516 ;;(port_mode (vams:net-consistence 'port_mode connlist))) 517 ) 518 (if (and port_object 519 port_type 520 (if (equal? port_object "quantity") 521 (port_mode (vams:net-consistence 'port_mode connlist)))) 522 (begin 523 (display "\t" p) 524 (display port_object p) 525 (display " " p) 526 (display net p) 527 (display " \t: " p) 528 ;; (if (equal? "quantity" (cadr signallist)) 529 ;; (display (cadddr signallist) p)) 530 (display " " p) 531 (display port_type p) 532 (display ";\n" p)) 533 (begin 534 (display "-- error in subnet : " p) 535 (display net p) 536 (newline p))))) 537 (vams:all-necessary-nets))))) 538 539 540;;; Architecture Statement Part 541;;; 542;;; According to IEEE 1076-1993 1.2.2: 543;;; 544;;; architecture_statement_part := 545;;; { concurrent_statement } 546;;; 547;;; According to IEEE 1076-1993 9: 548;;; 549;;; concurrent_statement := 550;;; block_statement 551;;; | process_statement 552;;; | concurrent_procedure_call_statement 553;;; | concurrent_assertion_statement 554;;; | concurrent_signal_assignment_statement 555;;; | component_instantiation_statement 556;;; | generate_statement 557;;; 558;;; Implementation note: 559;;; We currently does not support block statements, process statements, 560;;; concurrent procedure call statements, concurrent assertion statements, 561;;; concurrent signal assignment statements or generarte statements. 562;;; 563;;; Thus, we only support component instantiation statements. 564;;; 565;;; According to IEEE 1076-1993 9.6: 566;;; 567;;; component_instantiation_statement := 568;;; instantiation_label : instantiation_unit 569;;; [ generic_map_aspect ] [ port_map_aspect ] ; 570;;; 571;;; instantiated_unit := 572;;; [ COMPONENT ] component_name 573;;; | ENTITY entity_name [ ( architecture_identifier ) ] 574;;; | CONFIGURATION configuration_name 575;;; 576;;; Implementation note: 577;;; Since we are not supporting the generic parameters we will thus not 578;;; suppport the generic map aspect. We will support the port map aspect. 579;;; 580;;; Since we do not yeat support the component form we will not yet use 581;;; the component symbol based instantiated unit. 582;;; 583;;; Since we do not yeat support configurations we will not support the 584;;; we will not support the configuration symbol based form. 585;;; 586;;; This leaves us with the entity form, which we will support initially 587;;; using only the entity name. The architecture identifier could possibly 588;;; be supported by attribute value. 589 590;;; Component Declaration 591;;; 592;;; According to IEEE 1076-1993 4.5: 593;;; 594;;; component_declaration := 595;;; COMPONENT identifier [ IS ] 596;;; [ local_generic_clause ] 597;;; [ local_port_clause ] 598;;; END COMPONENT [ component_simple_name ] ; 599;;; 600;;; Implementation note: 601;;; The component declaration should match the entity declaration of the 602;;; same name as the component identifier indicates. Since we do not yeat 603;;; support the generic clause in the entity declaration we shall not 604;;; support it here either. We will however support the port clause. 605;;; 606;;; In the same fassion as before we will use the conditional IS symbol 607;;; as well as replicating the identifier as component simple name just to 608;;; be in line with good VAMS-93 practice and keep compilers happy. 609 610;;; writes the architecture body. 611;;; required all used packages, which are necessary for netlist- 612;;; generation, and the output-port. 613 614(define vams:write-architecture-statement-part 615 (lambda (packages p) 616 (begin 617 (display "-- Architecture statement part" p) 618 (newline p) 619 (for-each (lambda (package) 620 (begin 621 (let ((device (get-device package)) 622 (architecture 623 (gnetlist:get-package-attribute 624 package 625 "architecture"))) 626 (if (not (memv (string->symbol device) 627 (map string->symbol 628 (list "IOPAD" "IPAD" "OPAD" "HIGH" "LOW")))) 629 (begin 630 (display " \n " p) 631 632 ;; writes instance-label 633 (display package p) 634 (display " : ENTITY " p) 635 636 ;; writes entity name, which should instanciated 637 (display (get-device package) p) 638 639 ;; write the architecture of an entity in brackets after 640 ;; the entity, when necessary. 641 (if (not (equal? architecture "unknown")) 642 (begin 643 (display "(" p) 644 (if (equal? 645 (string-ref 646 (gnetlist:get-package-attribute package 647 "architecture") 0) 648 #\?) 649 (display (substring architecture 1) p) 650 (display architecture p)) 651 (display ")" p))) 652 (newline p) 653 654 ;; writes generic map 655 (vams:write-generic-map p package) 656 657 ;; writes port map 658 (vams:write-port-map package p) 659 660 (display ";\n" p)))))) 661 (vams:all-necessary-packages))))) 662 663 664 665;; Given a uref, prints all generics attribute => values, without some 666;; special attribs, like uref,source and architecture. 667;; Don't ask why .... it's not the right place to discuss this. 668;; requires the output-port and a uref 669 670(define vams:write-generic-map 671 (lambda (port uref) 672 (let ((new-ls (vams:all-used-generics 673 (vams:list-without-str-attrib 674 (vams:list-without-str-attrib 675 (vams:list-without-str-attrib 676 (gnetlist:vams-get-package-attributes uref) 677 "refdes") "source") "architecture") uref))) 678 (if (not (null? new-ls)) 679 (begin 680 (display "\tGENERIC MAP (\n" port) 681 (vams:write-component-attributes port uref new-ls) 682 (display ")\n" port)))))) 683 684 685 686;;; Port map aspect 687;;; 688;;; According to IEEE 1076-1993 5.6.1.2: 689;;; 690;;; port_map_aspect := PORT MAP ( port_association_list ) 691;;; 692;;; According to IEEE 1076-1993 4.3.2.2: 693;;; 694;;; association_list := 695;;; association_element { , association_element } 696 697;;; writes the port map of the component. 698;;; required output-port and uref. 699 700(define vams:write-port-map 701 (lambda (uref p) 702 (begin 703 (let ((pin-list (gnetlist:get-pins-nets uref))) 704 (if (not (null? pin-list)) 705 (begin 706 (display "\tPORT MAP (\t" p) 707 (vams:write-association-element (car pin-list) p) 708 (for-each (lambda (pin) 709 (display ",\n" p) 710 (display "\t\t\t" p) 711 (vams:write-association-element pin p)) 712 (cdr pin-list)) 713 (display ")" p))))))) 714 715 716;;; Association element 717;;; 718;;; According to IEEE 1076-1993 4.3.2.2: 719;;; 720;;; association_element := 721;;; [ formal_part => ] actual_part 722;;; 723;;; formal_part := 724;;; formal_designator 725;;; | function_name ( formal_designator ) 726;;; | type_mark ( formal_designator ) 727;;; 728;;; formal_designator := 729;;; generic_name 730;;; | port_name 731;;; | parameter_name 732;;; 733;;; actual_part := 734;;; actual_designator 735;;; | function_name ( actual_designator ) 736;;; | type_mark ( actual_designator ) 737;;; 738;;; actual_designator := 739;;; expression 740;;; | signal_name 741;;; | variable_name 742;;; | file_name 743;;; | OPEN 744;;; 745;;; Implementation note: 746;;; In the association element one may have a formal part or relly on 747;;; positional association. The later is doomed out as bad VAMS practice 748;;; and thus will the formal part allways be present. 749;;; 750;;; The formal part will not support either the function name or type mark 751;;; based forms, thus only the formal designator form is supported. 752;;; 753;;; Of the formal designator forms will generic name and port name be used 754;;; as appropriate (this currently means that only port name will be used). 755;;; 756;;; The actual part will not support either the function name or type mark 757;;; based forms, thus only the actual designator form is supported. 758 759 760;;; the purpose of this function is very easy: write OPEN if pin 761;;; unconnected and normal output if it connected. 762 763(define vams:write-association-element 764 (lambda (pin p) 765 (begin 766 (display (car pin) p) 767 (display " => " p) 768 (if (strncmp? (cdr pin) "unconnected_pin" 15) 769 (display "OPEN" p) 770 (display (vams:port-test pin) p))))) 771 772 773 774;;; writes all generics of a component into the 775;;; generic map. needs components uref, the generic-list and 776;;; an output-port 777 778(define vams:write-component-attributes 779 (lambda (port uref generic-list) 780 (if (not (null? generic-list)) 781 (let ((attrib (car generic-list)) 782 (value (gnetlist:get-package-attribute uref (car generic-list)))) 783 (begin 784 785 (if (string=? value "unknown") 786 (vams:write-component-attributes port uref (cdr generic-list)) 787 (begin 788 (display "\t\t\t" port) 789 (display attrib port) 790 (display " => " port) 791 (display value port) 792 (vams:write-component-attributes-helper port uref (cdr generic-list))))))))) 793 794(define vams:write-component-attributes-helper 795 (lambda (port uref generic-list) 796 (if (not (null? generic-list)) 797 (let ((attrib (car generic-list)) 798 (value (gnetlist:get-package-attribute uref (car generic-list)))) 799 (begin 800 801 (if (not (string=? value "unknown")) 802 (begin 803 (display ", " port) 804 (newline port) 805 (display "\t\t\t" port) 806 (display attrib port) 807 (display " => " port) 808 (display value port) 809 (vams:write-component-attributes-helper port uref (cdr generic-list))))))))) 810 811 812;;; ARCHITECTURE GENERATING PART 813;;; END 814 815;;; =================================================================================== 816 817;;; 818;;; REALLY IMPORTANT HELP FUNCTIONS 819 820 821;;; returns a list, whitout the specified string. 822;;; requires: a list and a string 823 824(define vams:list-without-str-attrib 825 (lambda (ls str) 826 (cond ((null? ls) '()) 827 (else 828 (append 829 (cond ((string=? (car ls) str) '()) 830 (else (list (car ls)))) 831 (vams:list-without-str-attrib (cdr ls) str)))))) 832 833 834 835;; returns all not default-setted generics 836;; After our definitions, all attribs, which values not started with a 837;; '?' - character. 838 839(define vams:all-used-generics 840 (lambda (ls uref) 841 (begin 842 (if (null? ls) 843 '() 844 (append 845 (if (equal? (string-ref (gnetlist:get-package-attribute uref (car ls)) 0) #\?) 846 '() 847 (list (car ls))) 848 (vams:all-used-generics (cdr ls) uref)))))) 849 850 851 852;; checks all pins of a net for consistence, under different points 853;; of view (pin-attributes). 854;; requires: a pin-attribute and the subnet 855 856(define vams:net-consistence 857 (lambda (attribute connlist) 858 (begin 859 (if (equal? connlist '()) 860 #f 861 (if (= (length connlist) 1) 862 (if (equal? attribute 'port_mode) 863 (if (equal? (gnetlist:get-attribute-by-pinnumber (car (car connlist)) 864 (car (cdr (car connlist))) 865 attribute) 866 'out) 867 #t 868 #f) 869 (append (gnetlist:get-attribute-by-pinnumber (car (car connlist)) 870 (car (cdr (car connlist))) 871 attribute))) 872 (if (equal? attribute 'port_mode) 873 (if (equal? (gnetlist:get-attribute-by-pinnumber (car (car connlist)) 874 (car (cdr (car connlist))) 875 attribute) 876 'out) 877 #t 878 (vams:net-consistence attribute (cdr connlist))) 879 (if (equal? (gnetlist:get-attribute-by-pinnumber (car (car connlist)) 880 (car (cdr (car connlist))) 881 attribute) 882 (vams:net-consistence attribute (cdr connlist))) 883 (append (gnetlist:get-attribute-by-pinnumber (car (car connlist)) 884 (car (cdr (car connlist))) 885 attribute)) 886 #f))))))) 887 888 889 890;; returns a string, where are all whitespaces replaced to underlines 891;; requires: a string only 892 893(define vams:change-all-whitespaces-to-underlines 894 (lambda (str) 895 (begin 896 (if (string-index str #\ ) 897 (begin 898 (if (= (string-index str #\ ) (- (string-length str) 1)) 899 (vams:change-all-whitespaces-to-underlines 900 (substring str 0 (- (string-length str) 1))) 901 (begin 902 (string-set! str (string-index str #\ ) #\_ ) 903 (vams:change-all-whitespaces-to-underlines str)))) 904 (append str))))) 905 906 907 908;; returns all nets, which a given list of pins are conneted to. 909;; requires: uref and its pins 910 911(define vams:all-pins-nets 912 (lambda (uref pins) 913 (if (null? pins) 914 '() 915 (append (list (car (gnetlist:get-nets uref (car pins)))) 916 (vams:all-pins-nets uref (cdr pins)))))) 917 918 919 920;; returns all nets, which a given list of urefs are connetd to 921;; requires: list of urefs :-) 922 923(define vams:all-packages-nets 924 (lambda (urefs) 925 (if (null? urefs) 926 '() 927 (append 928 (vams:all-pins-nets (car urefs) 929 (gnetlist:get-pins (car urefs))) 930 (vams:all-packages-nets (cdr urefs)))))) 931 932 933 934;; returns all ports from a list of urefs. 935;; important for hierachical netlists. in our definition ports are 936;; special components, which device-attributes a setted to "PORT". 937;; The port-attributes are saved on toplevel of this special component. 938;; requires: list of urefs 939 940(define vams:all-ports-in-list 941 (lambda (urefs) 942 (begin 943 (if (null? urefs) 944 '() 945 (append 946 (if (equal? "PORT" (get-device (car urefs))) 947 (list (car urefs)) 948 '()) 949 (vams:all-ports-in-list (cdr urefs))))))) 950 951 952 953;; returns all nets in the schematic, which not 954;; directly connected to a port. 955 956(define vams:all-necessary-nets 957 (lambda () 958 (vams:only-different-nets all-unique-nets 959 (vams:all-packages-nets 960 (vams:all-ports-in-list packages))))) 961 962 963 964;; returns all elements from ls, that are not in without-ls. 965;; a simple list function. 966(define (vams:only-different-nets ls without-ls) 967 (lset-difference equal? ls without-ls)) 968 969 970;; sort all port-components out 971 972(define vams:all-necessary-packages 973 (lambda () 974 (vams:only-different-nets packages 975 (vams:all-ports-in-list packages)))) 976 977 978 979;; if pin connetected to a port (special component), then return port. 980;; else return the net, which the pin is connetcted to. 981;; requires: a pin only 982 983(define vams:port-test 984 (lambda (pin) 985 (if (member (cdr pin) 986 (vams:all-packages-nets (vams:all-ports-in-list packages))) 987 (append (vams:which-port 988 pin 989 (vams:all-ports-in-list packages))) 990 (append (cdr pin))))) 991 992 993 994;; returns the port, when is in port-list, which the pin is connected to 995;; requires: a pin and a port-list 996 997(define vams:which-port 998 (lambda (pin ports) 999 (begin 1000 (if (null? ports) 1001 '() 1002 (if (equal? (cdr pin) 1003 (car (gnetlist:get-nets 1004 (car ports) 1005 (car (gnetlist:get-pins (car ports)))))) 1006 (append (car ports)) 1007 (append 1008 (vams:which-port pin (cdr ports)))))))) 1009 1010 1011 1012;; generate generic list for generic clause 1013;;((generic value) (generic value) .. ()) 1014 1015(define vams:generate-generic-list 1016 (lambda (ls) 1017 (if (null? ls) 1018 '() 1019 (append 1020 (if (not (or (string-prefix=? "refdes=" (car ls)) 1021 (string-prefix=? "source=" (car ls)) 1022 (string-prefix=? "architecture=" (car ls)))) 1023 (list 1024 (if (string-index (car ls) #\=) 1025 (list 1026 (substring (car ls) 0 (string-rindex (car ls) #\= 0)) 1027 (substring (car ls) (+ (string-rindex (car ls) #\= 0) 1028 (if (equal? (string-ref 1029 (car ls) 1030 (1+ (string-rindex (car ls) #\= 0))) 1031 #\?) 1032 2 1)) 1033 (string-length (car ls)))) 1034 (car ls))) 1035 '()) 1036 (vams:generate-generic-list (cdr ls)))))) 1037 1038 1039 1040;;; generates a port list of the current schematic, or returns 1041;;; a empty list, if no port reachable. 1042 1043(define vams:generate-port-list 1044 (lambda (uref) 1045 (let ((port-list (list '()))) 1046 (if (null? uref) 1047 '() 1048 (begin 1049 (for-each (lambda (pin) 1050 (append! port-list 1051 (list (list pin 1052 (gnetlist:get-attribute-by-pinnnumber uref pin "port_object") 1053 (gnetlist:get-attribute-by-pinnumber uref pin "port_type") 1054 (gnetlist:get-attribute-by-pinnumber uref pin "port_mode"))))) 1055 (gnetlist:get-pins uref)) 1056 (append (cdr port-list))))))) 1057 1058 1059 1060;;; gets the uref value from the top-attribs-list, which is assigned from gschem. 1061;;; only important for automatic-gnetlist-calls from gschem !!! 1062 1063(define vams:get-uref 1064 (lambda (liste) 1065 (begin 1066 (if (null? liste) 1067 '() 1068 (if (string-prefix=? "refdes=" (symbol->string (car liste))) 1069 (begin 1070 (append (substring (car liste) 5 1071 (string-length (car liste))))) 1072 (vams:get-uref (cdr liste))))))) 1073 1074 1075;;; set generate-mode to default (1), when not defined before. 1076(define generate-mode (if (defined? 'generate-mode) generate-mode '1)) 1077 1078 1079;;; set to-attribs list empty, when not needed. 1080(define top-attribs (if (defined? 'top-attribs) top-attribs '())) 1081 1082(display "loaded gnet-vams.scm\n") 1083 1084