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;;; Various support functions shamelessly stolen from the verilog code and 23;;; reshaped for vhdl. Doing this now saves labour when the implementations 24;;; starts to divert further. 25 26;;; Get port list of top-level Entity 27;;; THHE changed this to the urefs of the I/O-PAD symbols rather than the 28;;; net names. So the uref of the I/O port will become the port name in 29;;; the VHDLport clause. 30 31;;; THHE 32;;; 33;;; Since VHDL know about port directions, pins need a additional attribute. 34;;; The code assumes the attribute "type" (IN, OUT, INOUT) on each pin of a symbol. 35;;; In addition you can add the attribute "width" for a very simple definition of 36;;; busses. (Not complete yet!) 37;;; 38 39(define vhdl:get-top-port-list 40 (lambda () 41 ;; construct list 42 (list (vhdl:get-matching-urefs "device" "IPAD" packages) 43 (vhdl:get-matching-urefs "device" "OPAD" packages) 44 (vhdl:get-matching-urefs "device" "IOPAD" packages)))) 45 46;;; Get matching urefs 47(define vhdl:get-matching-urefs 48 (lambda (attribute value package-list) 49 (cond ((null? package-list) '()) 50 ((string=? (gnetlist:get-package-attribute (car package-list) 51 attribute) value) 52 (cons 53 (cons (car package-list) (gnetlist:get-package-attribute (car package-list) "width")) 54 (vhdl:get-matching-urefs attribute value (cdr package-list)))) 55 (else (vhdl:get-matching-urefs attribute value (cdr package-list)))) 56 57 ) 58) 59 60;;; THHE did not need it anymore 61; 62;(define vhdl:filter 63; (lambda (attribute value package-list) 64; (cond ((null? package-list) '()) 65; ((string=? (gnetlist:get-package-attribute (car package-list) 66; attribute) value) 67; (cons 68; (map (lambda (pin) 69; (car (gnetlist:get-nets (car package-list) pin))) 70; (pins (car package-list))) 71; (vhdl:filter attribute value (cdr package-list)))) 72; (else (vhdl:filter attribute value (cdr package-list))))) 73;) 74 75;;; Port Clause 76;;; 77;;; According to IEEE 1076-1993 1.1.1: 78;;; 79;;; entity_header := 80;;; [ formal_generic_clause ] 81;;; [ formal_port_clause ] 82;;; 83;;; generic_clause := 84;;; GENERIC ( generic_list ) ; 85;;; 86;;; port_clause := 87;;; PORT ( port_list ) ; 88;;; 89;;; According to IEEE 1076-1993 1.1.1.2: 90;;; 91;;; port_list := port_interface_list 92;;; 93;;; According to IEEE 1076-1993 4.3.2.1: 94;;; 95;;; interface_list := interface_element { ; interface_element } 96;;; 97;;; interface_element := interface_declaration 98;;; 99;;; According to IEEE 1076-1993 4.3.2: 100;;; 101;;; interface_declaration := 102;;; interface_constant_declaration 103;;; | interface_signal_declaration 104;;; | interface_variable_declaration 105;;; | interface_file_declaration 106;;; 107;;; interface_signal_declaration := 108;;; [ SIGNAL ] identifier_list : [ mode ] subtype_indication [ BUS ] 109;;; [ := static_expression ] 110;;; 111;;; mode := IN | OUT | INOUT | BUFFER | LINKAGE 112;;; 113;;; Implementation note: 114;;; Since the port list must contain signals will only the interface 115;;; signal declaration of the interface declaration be valid. Further, 116;;; we may safely assume that the SIGNAL symbol will not be needed. 117;;; The identifier list is reduced to a signle name entry, mode is set 118;;; to in, out or inout due to which part of the port list it comes from. 119;;; The mode types supported are in, out and inout where as buffer and 120;;; linkage mode is not supported. The subtype indication is currently 121;;; hardwired to standard logic, but should be controlled by attribute. 122;;; There is currently no support for busses and thus is the BUS symbol 123;;; no being applied. Also, there is currently no static expression 124;;; support, this too may be conveyed using attributes. 125;;; 126 127;;; This little routine writes a single pin on the port clause. 128;;; It assumes a list containing (portname, mode, type) such as 129;;; (CLK in Std_Logic width). 130;;; 131;;; THHE If you added a attribute width=n to a pin or to a I/O-PAD, you get 132;;; portname : IN Std_Logic_Vector(width-1 downto 0) 133;;; 134(define vhdl:write-port 135 (lambda (port p) 136 (if (not (null? port)) 137 (begin 138 (if (string=? (cadddr port) "unknown") 139 (begin 140 (display (car port) p) 141 (display " : " p) 142 (display (cadr port) p) 143 (display " " p) 144 (display (caddr port) p) 145 ) 146 ) 147 (if (not (string=? (cadddr port) "unknown")) 148 (begin 149 (display (car port) p) 150 (display " : " p) 151 (display (cadr port) p) 152 (display " " p) 153 (display (caddr port) p) 154 (display "_Vector(" p) 155 (display (- (string->number(cadddr port)) 1) p) 156 (display " downto 0)" p) 157 ) 158 ) 159 ) 160 ) 161 ) 162) 163 164;;; This little routine will actually write the full port clause given a list 165;;; of pins, such as ((CLK in Std_Logic) (D in Std_Logic) (Q out Std_Logic)) 166 167(define vhdl:write-port-list 168 (lambda (list p) 169 (if (not (null? list)) 170 (begin 171 (display " PORT (" p) 172 (newline p) 173 (display " " p) 174 (vhdl:write-port (car list) p) 175 (for-each (lambda (pin) 176 (begin 177 (display ";" p) 178 (newline p) 179 (display " " p) 180 (vhdl:write-port pin p) 181 ) 182 ) 183 (cdr list)) 184 (display ");" p) 185 (newline p) 186 ) 187 ) 188 ) 189) 190 191;;; This is the real thing. It will take a port-list arrangement. 192;;; 193;;; The port-list is a list containing three list: 194;;; (in-port-list, out-port-list, inout-port-list) 195;;; 196;;; These lists will be transformed into a single list containing the full 197;;; pin information. Currently is this done with hardwired to Std_Logic. 198 199(define vhdl:write-port-clause 200 (lambda (port-list p) 201 (let ((in (car port-list)) 202 (out (cadr port-list)) 203 (inout (caddr port-list))) 204 (vhdl:write-port-list 205 (append 206 (map (lambda (pin) 207 (list (car pin) "in" "Std_Logic" (cdr pin))) in) 208 (map (lambda (pin) 209 (list (car pin) "out" "Std_Logic" (cdr pin))) out) 210 (map (lambda (pin) 211 (list (car pin) "inout" "Std_Logic" (cdr pin))) inout) 212 ) 213 p 214 ) 215 ) 216 ) 217) 218 219;;; Primary unit 220;;; 221;;; According to IEEE 1076-1993 11.1: 222;;; 223;;; primary_unit := 224;;; entity_declaration 225;;; | configuration_declaration 226;;; | package_declaration 227;;; 228;;; Implementation note: 229;;; We assume that gEDA does not generate either a configuration or 230;;; package declaration. Thus, only a entity declaration will be generated. 231;;; 232;;; According to IEEE 1076-1993 1.1: 233;;; 234;;; entity_declaration := 235;;; ENTITY identifier IS 236;;; entity_header 237;;; entity_declarative_part 238;;; [ BEGIN 239;;; entity_statement_part ] 240;;; END [ ENTITY ] [ entity_simple_name ] ; 241;;; 242;;; Implementation note: 243;;; We assume that no entity declarative part and no entity statement part 244;;; is to be produced. Further, it is good custom in VHDL-93 to append 245;;; both the entity keyword as well as the entity simple name to the 246;;; trailer, therefore this is done to keep VHDL compilers happy. 247;;; 248;;; According to IEEE 1076-1993 1.1.1: 249;;; 250;;; entity_header := 251;;; [ formal_generic_clause ] 252;;; [ formal_port_clause ] 253;;; 254;;; Implementation note: 255;;; Initially we will assume that there is no generic clause but that there 256;;; is an port clause. We would very much like to have generic and the port 257;;; clause should be conditional (consider writting a test-bench). 258;;; 259 260(define vhdl:write-primary-unit 261 (lambda (module-name port-list p) 262 (begin 263 ; Entity header 264 (display "-- Entity declaration" p) 265 (newline p) 266 (newline p) 267 (display "ENTITY " p) 268 (display module-name p) 269 (display " IS" p) 270 (newline p) 271 ; entity_header := [ generic_clause port_clause ] 272 ; Insert generic_clause here when time comes 273 ; port_clause 274 ;;; <DEBUG> 275 ;(newline) 276 ;(display "The schematic contains the following devices:") 277 ;(newline) 278 ;(display unique-devices) 279 ;(newline) 280 ;(newline) 281 ;;; </DEBUG> 282 (vhdl:write-port-clause port-list p) 283 ; entity_declarative_part is assumed not to be used 284 ; entity_statement_part is assumed not to be used 285 ; Entity trailer 286 (display "END " p) 287 (display module-name p) 288 (display ";" p) 289 (newline p) 290 (newline p) 291 ) 292 ) 293) 294 295;; 296;; Secondary Unit Section 297;; 298 299;;; Component Declaration 300;;; 301;;; According to IEEE 1076-1993 4.5: 302;;; 303;;; component_declaration := 304;;; COMPONENT identifier [ IS ] 305;;; [ local_generic_clause ] 306;;; [ local_port_clause ] 307;;; END COMPONENT [ component_simple_name ] ; 308;;; 309;;; Implementation note: 310;;; The component declaration should match the entity declaration of the 311;;; same name as the component identifier indicates. Since we do not yeat 312;;; support the generic clause in the entity declaration we shall not 313;;; support it here either. We will however support the port clause. 314;;; 315;;; In the same fassion as before we will use the conditional IS symbol 316;;; as well as replicating the identifier as component simple name just to 317;;; be in line with good VHDL-93 practice and keep compilers happy. 318 319(define vhdl:write-component-declarations 320 (lambda (device-list p) 321 (begin 322 ;;; <DEBUG> 323 ;(display "refdes : package : (( IN )( OUT )(INOUT ))") 324 ;(newline) 325 ;(display "========================================") 326 ;(newline) 327 ;;; </DEBUG> 328 (for-each 329 (lambda (device) 330 (begin 331 ; Hmm... I just grabbed this if stuff... do I need it? 332 (if (not (memv (string->symbol device) ; ignore specials 333 (map string->symbol (list "IOPAD" "IPAD" "OPAD" "HIGH" "LOW")))) 334 (begin 335 (display " COMPONENT " p) 336 (display device p) 337 ;(display " IS" p) 338 (newline p) 339 ; Generic clause should be inserted here 340 ;;; <DEBUG> 341 ;(display (find-device packages device)) 342 ;(display " : ") 343 ;(display device) 344 ;(display " : ") 345 ;(display (vhdl:get-device-port-list 346 ; (find-device packages device) 347 ; ) 348 ;) 349 ;(newline) 350 ;;; </DEBUG> 351 (vhdl:write-port-clause (vhdl:get-device-port-list 352 (find-device packages device)) 353 p) 354 (display " END COMPONENT " p) 355 (display ";" p) 356 (newline p) 357 (newline p) 358 ) 359 ) 360 ) 361 ) device-list 362 ) 363 ) 364 ) 365) 366 367;;; THHE 368;;; Build the port list from the symbols 369;;; 370;;; ... wouldn't it be better to feed get-pins, get-attribute-by-pinnumber and co. 371;;; with the device rather than the component? pin names and atributes are locked to 372;;; the symbol and not to the instance of the symbol in the sheet! 373 374(define vhdl:get-device-port-list 375 (lambda (device) 376 ;; construct list 377 (list (vhdl:get-device-matching-pins device (gnetlist:get-pins device) "IN") 378 (vhdl:get-device-matching-pins device (gnetlist:get-pins device) "OUT") 379 (vhdl:get-device-matching-pins device (gnetlist:get-pins device) "INOUT") 380 ) 381 ) 382) 383 384;;; THHE 385;;; get a list of all pins of a given type 386;;; 387 388(define vhdl:get-device-matching-pins 389 (lambda (device pin-list value) 390 (cond ((null? pin-list) '()) 391 ((string=? (gnetlist:get-attribute-by-pinnumber device (car pin-list) "pintype" ) 392 value) 393 (cons 394 (cons (car pin-list) (gnetlist:get-attribute-by-pinnumber device (car pin-list) "width")) 395 (vhdl:get-device-matching-pins device (cdr pin-list) value)) 396 ) 397 (else (vhdl:get-device-matching-pins device (cdr pin-list) value)) 398 ) 399 ) 400) 401 402;;; THHE 403;;; build a list of all unique devices in in the list 404;;; 405 406(define vhdl:get-unique-devices 407 (lambda (device-list) 408 (cond ((null? device-list) '()) 409 ((not (contains? (cdr device-list) (car device-list))) 410 (append (vhdl:get-unique-devices (cdr device-list)) 411 (list (car device-list)))) 412 (else (vhdl:get-unique-devices (cdr device-list))) 413 ) 414 ) 415) 416 417;;; THHE 418;;; build a list of all unique devices in the schematic 419;;; 420 421(define unique-devices 422 (lambda nil 423 (vhdl:get-unique-devices (map get-device packages)) 424)) 425 426 427;;; Signal Declaration 428;;; 429;;; According to IEEE 1076-1993 4.3.1.2: 430;;; 431;;; signal_declaration := 432;;; SIGNAL identifier_list : subtype_indication [ signal_kind ] 433;;; [ := expression ] ; 434;;; 435;;; signal_kind := REGISTER | BUS 436;;; 437;;; Implementation note: 438;;; Currently will the identifier list be reduced to a single entry. 439;;; There is no support for either register or bus type of signal kind. 440;;; Further, no default expression is being supported. 441;;; The subtype indication is hardwired to Std_Logic. 442 443(define vhdl:write-signal-declarations 444 (lambda (p) 445 (begin 446 (for-each 447 (lambda (signal) 448 (begin 449 (display " SIGNAL " p) 450 (display signal p) 451 (display " : Std_Logic;" p) 452 (newline p) 453 ) 454 ) 455 all-unique-nets) 456 ) 457 ) 458) 459 460;;; Architecture Declarative Part 461;;; 462;;; According to IEEE 1076-1993 1.2.1: 463;;; 464;;; architecture_declarative_part := 465;;; { block_declarative_item } 466;;; 467;;; block_declarative_item := 468;;; subprogram_declaration 469;;; | subprogram_body 470;;; | type_declaration 471;;; | subtype_declaration 472;;; | constant_declaration 473;;; | signal_declaration 474;;; | shared_variable_declaration 475;;; | file_declaration 476;;; | alias_declaration 477;;; | component_declaration 478;;; | attribute_declaration 479;;; | attribute_specification 480;;; | configuration_specification 481;;; | disconnection_specification 482;;; | use_clause 483;;; | group_template_declaration 484;;; | group_declaration 485;;; 486;;; Implementation note: 487;;; There is currently no support for programs or procedural handling in 488;;; gEDA, thus will all declarations above involved in thus activites be 489;;; left unused. This applies to subprogram declaration, subprogram body, 490;;; shared variable declaration and file declaration. 491;;; 492;;; Further, there is currently no support for type handling and therefore 493;;; will not the type declaration and subtype declaration be used. 494;;; 495;;; The is currently no support for constants, aliases, configuration 496;;; and groups so the constant declaration, alias declaration, configuration 497;;; specification, group template declaration and group declaration will not 498;;; be used. 499;;; 500;;; The attribute passing from a gEDA netlist into VHDL attributes must 501;;; wait, therefore will the attribute declaration and attribute 502;;; specification not be used. 503;;; 504;;; The disconnection specification will not be used. 505;;; 506;;; The use clause will not be used since we pass the responsibility to the 507;;; primary unit (where it �s not yet supported). 508;;; 509;;; The signal declation will be used to convey signals held within the 510;;; architecture. 511;;; 512;;; The component declaration will be used to convey the declarations of 513;;; any external entity being used within the architecture. 514 515(define vhdl:write-architecture-declarative-part 516 (lambda (p) 517 (begin 518 ; Due to my taste will the component declarations go first 519 ; XXX - Broken until someday 520 ; THHE fixed today ;-) 521 (vhdl:write-component-declarations (unique-devices) p) 522 ; Then comes the signal declatations 523 (vhdl:write-signal-declarations p) 524 ) 525 ) 526) 527 528;;; Architecture Statement Part 529;;; 530;;; According to IEEE 1076-1993 1.2.2: 531;;; 532;;; architecture_statement_part := 533;;; { concurrent_statement } 534;;; 535;;; According to IEEE 1076-1993 9: 536;;; 537;;; concurrent_statement := 538;;; block_statement 539;;; | process_statement 540;;; | concurrent_procedure_call_statement 541;;; | concurrent_assertion_statement 542;;; | concurrent_signal_assignment_statement 543;;; | component_instantiation_statement 544;;; | generate_statement 545;;; 546;;; Implementation note: 547;;; We currently does not support block statements, process statements, 548;;; concurrent procedure call statements, concurrent assertion statements, 549;;; concurrent signal assignment statements or generarte statements. 550;;; 551;;; Thus, we only support component instantiation statements. 552;;; 553;;; According to IEEE 1076-1993 9.6: 554;;; 555;;; component_instantiation_statement := 556;;; instantiation_label : instantiation_unit 557;;; [ generic_map_aspect ] [ port_map_aspect ] ; 558;;; 559;;; instantiated_unit := 560;;; [ COMPONENT ] component_name 561;;; | ENTITY entity_name [ ( architecture_identifier ) ] 562;;; | CONFIGURATION configuration_name 563;;; 564;;; Implementation note: 565;;; Since we are not supporting the generic parameters we will thus not 566;;; suppport the generic map aspect. We will support the port map aspect. 567;;; 568;;; Since we do not yeat support the component form we will not yet use 569;;; the component symbol based instantiated unit. 570;;; 571;;; Since we do not yeat support configurations we will not support the 572;;; we will not support the configuration symbol based form. 573;;; 574;;; This leaves us with the entity form, which we will support initially 575;;; using only the entity name. The architecture identifier could possibly 576;;; be supported by attribute value. 577 578(define vhdl:write-architecture-statement-part 579 (lambda (packages p) 580 (begin 581 (display "-- Architecture statement part" p) 582 (newline p) 583 (vhdl:write-component-instantiation-statements packages p) 584 (display "-- Signal assignment part" p) 585 (newline p) 586 (vhdl:write-signal-assignment-statements packages p) 587 ) 588 ) 589) 590;;; THHE 591;;; write component instantiation for each component in the sheet 592;;; 593 594(define vhdl:write-component-instantiation-statements 595 (lambda (packages p) 596 (for-each (lambda (package) 597 (begin 598 (let ((device (get-device package))) 599 (if (not (memv (string->symbol device) 600 (map string->symbol 601 (list "IOPAD" "IPAD" "OPAD" 602 "HIGH" "LOW")))) 603 (begin 604 (display " " p) 605 ; label 606 (display package p) 607 (display " : " p) 608 ; entity name 609 (display (get-device package) p) 610 (newline p) 611 ; Generic map aspect should go in here 612 ; Port map aspect 613 (vhdl:write-port-map package p) 614 (display ";" p) 615 (newline p) 616 (newline p) 617 ) 618 ) 619 ) 620 ) 621 ) 622 packages) 623 ) 624) 625 626;;; THHE 627;;; Write the signal assignment for the top-level ports 628;;; Since I like to have the urefs as port names in the top 629;;; level entity, I have to assign them to the correspinding nets as well 630 631(define vhdl:write-signal-assignment-statements 632 (lambda (packages p) 633 (begin 634 (for-each (lambda (port-ass) (vhdl:write-in-signal-assignment port-ass p)) 635 (vhdl:get-top-level-ports packages "IPAD")) 636 (for-each (lambda (port-ass) (vhdl:write-out-signal-assignment port-ass p)) 637 (vhdl:get-top-level-ports packages "OPAD")) 638 (for-each (lambda (port-ass) (vhdl:write-inout-signal-assignment port-ass p)) 639 (vhdl:get-top-level-ports packages "IOPAD")) 640 ) 641 ) 642) 643;;; THHE 644;;; get a list of the top-level ports (the urefs of the I/O-PADs) 645 646(define vhdl:get-top-level-ports 647 (lambda (package-list pad-type) 648 (cond ((null? package-list) '()) 649 ((string=? (get-device (car package-list)) pad-type) 650 (cons (cons (car package-list) 651 (cdar (gnetlist:get-pins-nets (car package-list))) ) 652 (vhdl:get-top-level-ports (cdr package-list ) pad-type ))) 653 (else (vhdl:get-top-level-ports (cdr package-list ) pad-type )) 654 655 ) 656 ) 657) 658 659;;;THHE 660(define vhdl:write-in-signal-assignment 661 (lambda (port-assignment p) 662 (begin 663 (display (cdr port-assignment) p) 664 (display " <= " p) 665 (display (car port-assignment) p) 666 (display ";" p) 667 (newline p) 668 ) 669 ) 670) 671 672;;;THHE 673(define vhdl:write-out-signal-assignment 674 (lambda (port-assignment p) 675 (begin 676 (display (car port-assignment) p) 677 (display " <= " p) 678 (display (cdr port-assignment) p) 679 (display ";" p) 680 (newline p) 681 ) 682 ) 683) 684 685 686;;;THHE 687(define vhdl:write-inout-signal-assignment 688 (lambda (port-assignment p) 689 (begin 690 (vhdl:write-in-signal-assignment port-assignment p) 691 (vhdl:write-out-signal-assignment port-assignment p) 692 ) 693 ) 694) 695 696;;; Port map aspect 697;;; 698;;; According to IEEE 1076-1993 5.6.1.2: 699;;; 700;;; port_map_aspect := PORT MAP ( port_association_list ) 701;;; 702;;; According to IEEE 1076-1993 4.3.2.2: 703;;; 704;;; association_list := 705;;; association_element { , association_element } 706 707(define vhdl:write-port-map 708 (lambda (package p) 709 (begin 710 (let ((pin-list (gnetlist:get-pins-nets package))) 711 (if (not (null? pin-list)) 712 (begin 713 (display " PORT MAP (" p) 714 (newline p) 715 (display " " p) 716 (vhdl:write-association-element (car pin-list) p) 717 (for-each (lambda (pin) 718 (display "," p) 719 (newline p) 720 (display " " p) 721 (vhdl:write-association-element pin p)) 722 (cdr pin-list)) 723 (display ")" p) 724 ) 725 ) 726 ) 727 728 ) 729 ) 730) 731 732;;; Association element 733;;; 734;;; According to IEEE 1076-1993 4.3.2.2: 735;;; 736;;; association_element := 737;;; [ formal_part => ] actual_part 738;;; 739;;; formal_part := 740;;; formal_designator 741;;; | function_name ( formal_designator ) 742;;; | type_mark ( formal_designator ) 743;;; 744;;; formal_designator := 745;;; generic_name 746;;; | port_name 747;;; | parameter_name 748;;; 749;;; actual_part := 750;;; actual_designator 751;;; | function_name ( actual_designator ) 752;;; | type_mark ( actual_designator ) 753;;; 754;;; actual_designator := 755;;; expression 756;;; | signal_name 757;;; | variable_name 758;;; | file_name 759;;; | OPEN 760;;; 761;;; Implementation note: 762;;; In the association element one may have a formal part or relly on 763;;; positional association. The later is doomed out as bad VHDL practice 764;;; and thus will the formal part allways be present. 765;;; 766;;; The formal part will not support either the function name or type mark 767;;; based forms, thus only the formal designator form is supported. 768;;; 769;;; Of the formal designator forms will generic name and port name be used 770;;; as appropriate (this currently means that only port name will be used). 771;;; 772;;; The actual part will not support either the function name or type mark 773;;; based forms, thus only the actual designator form is supported. 774 775(define vhdl:write-association-element 776 (lambda (pin p) 777 (begin 778 (display (car pin) p) 779 (display " => " p) 780 (if (strncmp? "unconnected_pin" (cdr pin) 15) 781 (display "OPEN" p) 782 (display (cdr pin) p))))) 783 784;;; Secondary unit 785;;; 786;;; According to IEEE 1076-1993 11.1: 787;;; 788;;; secondary_unit := 789;;; architecture_body 790;;; | package_body 791;;; 792;;; Implementation note: 793;;; Since we are not likely to create packages in gEDA in the near future 794;;; we will only support the architecture body. 795;;; 796;;; According to IEEE 1076-1993 1.2: 797;;; 798;;; architecture_body := 799;;; ARCHITECTURE identifier OF entity_name IS 800;;; architecture_declarative_part 801;;; BEGIN 802;;; architecture_statement_part 803;;; END [ ARCHITECTURE ] [ architecture_simple_name ] ; 804;;; 805;;; Implementation note: 806;;; The identifier will identify one of many architectures for an entity. 807;;; Since we generate only an netlist architecture we will lock this to be 808;;; "netlist" for the time being. Just as with the entity declaration we 809;;; will use good VHDL-93 custom to add the architecture keyword as well 810;;; as the architecture simple name to the trailer to keep compilers happy. 811 812(define vhdl:write-secondary-unit 813 (lambda (module-name p) 814 (display "-- Secondary unit" p) 815 (newline p) 816 (display "ARCHITECTURE netlist OF " p) 817 (display module-name p) 818 (display " IS" p) 819 (newline p) 820 ; architecture_declarative_part 821 (vhdl:write-architecture-declarative-part p) 822 (display "BEGIN" p) 823 (newline p) 824 ; architecture_statement_part 825 (vhdl:write-architecture-statement-part packages p) 826 (display "END netlist;" p) 827 (newline p) 828 ) 829) 830 831;;; Top level function 832;;; Write structural VHDL representation of the schematic 833;;; 834(define vhdl 835 (lambda (output-filename) 836 (let ((port (open-output-file output-filename)) 837 (module-name (gnetlist:get-toplevel-attribute "module-name")) 838 (port-list (vhdl:get-top-port-list))) 839 (begin 840 841;; No longer needed... especially since VHDL isn't a valid mode. :-) 842;; (gnetlist:set-netlist-mode "VHDL") 843 (display "-- Structural VHDL generated by gnetlist" port) 844 (newline port) 845 ; design_file := design_unit { design_unit } 846 ; design_unit := context_clause library_unit 847 (vhdl:write-context-clause port) 848 ; library_unit := primary_unit secondary_unit 849 (vhdl:write-primary-unit module-name port-list port) 850 (newline port) 851 (vhdl:write-secondary-unit module-name port) 852 ) 853 (close-output-port port) 854 ) 855 ) 856) 857 858;;; Context clause 859;;; 860;;; According to IEEE 1076-1993 11.3: 861;;; 862;;; context_clause := { context_item } 863;;; context_item := library_clause | use_clause 864;;; 865;;; Implementation note: 866;;; Both library and use clauses will be generated, eventually... 867;;; What is missing is the information from gEDA itself, i think. 868 869(define vhdl:write-context-clause 870 (lambda (p) 871 (display "-- Context clause" p) 872 (newline p) 873 (display "library IEEE;" p) 874 (newline p) 875 (display "use IEEE.Std_Logic_1164.all;" p) 876 (newline p) 877 ) 878) 879 880 881