Thoughts on Design Architect in an Actel Xilinx world. By Quentin (Monitor Thrower) Diduck & Aaron (Not Yet Recovering) Candy The first thing to keep in mind when using this software is in general, it's BAD. Do not trust this software. This software creates a lot of files, and subdirectories, so start it up in your working directory not your root. Also it is recommended to put the following start up into your .cshrc setenv MGC_WD `pwd` setenv QUICK_HDL $MGC_HOME/lib/quickhdl.ini Trust me it will just make life easier, later on when you start to simulate. Now that we have taken care of the trivial stuff. We will discuss some useful techniques and some of the problems with DA. The best way to learn any new software is to "play with it". This software is no exception, however it does some things that are unnatural to most users. The best way to think of DA is to consider it a CAD tool operating system, that happens to include most of the programs you will need in order to build your design. These subprograms, if you will, are things like schematic capture, VHDL compiler, and library functions. Each device runs as its own entity ontop of DA. One of the first things you may notice is that when you run something like a schematic session the top menues will change. However if you click on the DA back ground the menues go back to DA's default menues. This may be a little confusing at first, but once you get use to it, it is infact quite useful. I highly recommend getting familiar with the session pallette, this is a good and quick way to start up any function you will need, as well remember that this too does change when you start up a function. Clicking on the background of DA brings this pallette back. Using the top menues tends to be slow and combersome and should be avoided. There are short cut keys located on the bottom of the screen. Often these boxes will contain upto three commands to use the first one just press the key, to use the second hold shift while pressing the key, to use the third hold control and press the key. You will find that once you become familar with these short cuts they will save time, and once you start your project you will have to save as much time as possible. The middle mouse button has a special purpose and reduces the need to use the keyboard, many things can be done with a simple stroke of a mouse. To see all of the wonderful things you can do with the middle mouse button, draw a reasonable "?¨ with the middle mouse button anywhere on the DA screen. Things like rotate, copy, move are all possible. The nightmares of DA: performing a Save As and never being able to find a file by that name ever again. Yes this can happen to you, particualarly in schematic capture. The one thing to keep in mind is that if you do multiple saves with the same file name you can get recall them by version number. To do this choose Open Sheet ... and then use navigator to find your file. Now press Options to choose your version that you need (this little procedure saved me more than once). As much as you might use schematic capture off the start, you will most likely use mainly VHDL for your project. VHDL under DA is nice, things compile fast, simulate nicely, and are usually completely and utterly useless in the real world. Yes its true if you use DA's VHDL compiler it will never, ever, ever, work on any chip on this planet. So what do you do? Well, do all of your labs using DA. You never have to burn them into a chip. However when doing your project do not build your entire design under DA and then try port it to ACTMAP. This will cause great pain, suffering, and the temptation to throw a monitor out a window (I have seen people actually start to pick them up). Another point on the topic of projects, if it contains more than a ten state, state machine choose another project. The method to follow when building your project is to use DA's wonderful compiler to build a small portion of your project at a time, say 2 or 3 states of a state machine. Then port it over to the evil ACTMAP utility to see what it makes. Back anotate and simulate that part of you design, ensure that it functions correctly, then add a few more states under DA. By the way ACTMAP voilates, and mutilates you original file (how nice). That's right, you will reload it under DA and you will get a syntax error on line 1, but everything is correct in your code. This frustrating little flaw took me aproximately 30 minutes to figure out a solution. The best thing is prevention. Before you send anything to ACTMAP copy it to a work file name such as act1.vhd and just reuse that file name over and over. This is the simplest solution. However there may be a time that you forget to do this and you will corrupt your original. So this is how you fix it: first open a new VHDL file. Then using the copy command Copy all of your original file and then Paste it into the new file. Make sure you use DA to do this and not an editor! If you use a Text Editor (other than something like VI) you will have other problems. If you copy code, or write code in an editor and then transfer it to ACTMAP, you will have problems. ACTMAP is just plan old poorly writen code. Your text editor code will work fine under DA, but will choke under ACTMAP. If you have made this mistake as I did, there is a solution, not a nice one, but there is one. Load your file into DA or VI (in VI you can actually see the characters that are causing the problem) and go to the end of every line and press the backspace key once. Under DA your cursor will not move but a control character placed by the previous editor will be removed (the non-graphic character). For more information on ACTMAP and VHDL I recommend reading the web page named "How to Write VHDL for Actel FPGA Synthesis" under the EE552 home page. For those of you who try to use the Xilinx chip ( We did the switch half-way through the term after ACTMAP nearly drove us to insanity) your battles are much diffrent, synopsis and all functions will not be covered here. However I will tell you about some of the xmake function errors. The first one you will probably encounter is that you should use a Primary Global buffer pin. You can get around this by putting the statement: set_pad_type -no_clock PIN-NAME This will change the error into just a warning. The above line has to be entered above the insert_pads command. A Warning that may need to be corrected, particularly if your state machine slides through states, is as follows: *** PPR: WARNING 6811: This design has 96 purely combinational loops. Such loops should be avoided. If at all possible, please modify the design to eliminate all unclocked feedback paths. To permit path analysis during design implementation, all loops will be broken by cutting out the last source-to-load connection. A consequence is that the analyzer will not account for ANY paths through that connection. This may cause the final performance of your design to be sub-optimal. You can instruct the path analyzer to cut out connections of your choice, by using timespec "ignore" attributes. For details, consult the PPR documentation. This warning was what resulted from a xmake of an 87 state-machine. The following warnings in general can be ignored: *** PPR: WARNING 6107: The following MAP symbols HMAP symbol 'count/count/U315_map' were not successfully used, either beacuse (1) an error was made when assigning signals to the MAP pins; or (2) the underlying logic was changed by the trimming process, invalidating the MAP definition. Because of the second possibility, the MAPs listed below will not be considered errors. You may wish to check the MAP definitions and/or the Logic Trimming section of the XNFPREP report file to determine why these MAPs could not be used. *** PPR: WARNING 7034: In categories of paths that have NO timing specifications, the design has 32 path end-point pairs. Note that there may be multiple paths between any listed pair of end-points. To limit the number of paths reported in each category, set PPR parameter show_tsi_paths = . *** PPR: WARNING 7028: The design has flip-flops with asynchronous set/reset controls (PRE/SD or CLR/RD pins). When PPR analyzes design timing, it does not trace paths through the asynchronous set/reset input and on through the Q output. If you want PPR to control the delay on paths through asynchronous set/reset pins, you must split the delay requirement into two segments: one ending at the set/reset input, and the other beginning at the flip-flop output. If you want PPR not to analyze paths that lead to asynchronous set/reset pins, attach an IGNORE specification to the pin(s) or signal(s). By default, XDelay reports all paths through asynchronous set/reset pins. To prevent XDelay from showing these paths, use FlagBlk CLB_Disable_SR_Q on the appropriate flip-flops. If you run xmake and think that it is locked up it probably isn't, half of our project would take on the order of 45 minutes to xmake. A helpful hint is to rlogin to another terminal in the room that is not in use or has someone just running netscape and run xmake on that terminal, in this way you can run multiple xmake sessions way fairly quickly. For a good solid description on how to use the Xilinx RPB and all its tools I highly recommend reading Ray Stills and Shazia Mardhani document. The following section contains some general hints and tips you may find useful. General Hints and Tips After a long, stressful term I look back and think about all that could have been had I done several things differently. This is just a list of advice that may or may not apply to you, but if it does, learn it, live it, love it. 1.) Start Early. I know that at the beginning of the term you think you have more than enough time to finish your project, but you don't. Inevitably problems with the CAD tools will be had. Whether it be your design is too large and has to be scaled back or your design does not have the proper behavior after its translated by the CAD tools something will happen. 2.) Take Small Steps Don't try to translate your design from vhdl to an FPGA readable form all at once. Do this is stages. Very small stages. I would recommend doing it one state at a time. This way you will know what part of your design is not be translated properly. Keeping things very modular is very benificial. 3.) EDN2VHDL If you are using the 'downto' declaration for your std_logic_vectors make sure to type: edn2vhdl fam:act1 BUSORDER:DOWN Otherwise the translator will make the data on all your busses appear in reverse order, which is quite a pain in the posterior. 4.) Backup Your Files When using actmapw, strange things seem to happen to your code. Sometimes invisible characters will be appended to every line of code. Unless you want to go through every line and delete these characters make backups of all files you plan to send to actmapw. 5.) Tri-State Lines These can be implememted with both XILINX and ACTEL, but only with great difficulty. For your own sanity, if at all possible, do not use tri-state lines. 6.) Pull-up/Pull-down Resistors If your external interface uses switches, make sure that you put in pull-up or pull-down resistors as required. Asynchronus Interfacing One of the more exotic concepts used in our design was asynchronus handshaking. Originally we planned to implement the asynchronus data transfer using a single tri-state line, but as noted above this was as fun as getting kicked in the bollocks. We changed our design to use a complete handshaking system. If you have a design that requires asynchronus input and/or output the following may be of use. It is code used for complete handshaking for device input and output. Just insert the appropriate code wherever you need to get input or send output. Even if you are using asynchronus interfaces, make your internal design synchronus, responding to only one edge of the clock. Otherwise you'll get very strange results after translating your design. The use of these states may require additional input and output signals: in_ready : in std_logic; read_done : out std_logic; out_ready : out std_logic; write_done : in std_logic; For input use : -- read_in1 is the initial handshaking state. The state machine -- continually reads the data on the input bus, until the data sender -- asserts the in_ready line, which indicates the data is valid. when read_in1=> in_spot <= input; --input is whatever data you are recieving from the data --producer. in_spot is wherever the data is being put. if( in_ready='1') then next_state <= read_in2; elsif( in_ready='0') then next_state <= read_in1; end if; -- read_in2 is the second handshaking state. After the state -- machine has read the data off the bus, it asserts the read_done -- signal to tell the data sender that the data has been read. when read_in2=> read_done <= 1; next_state <= read_in3; -- read_in3 is the third stage of handshaking. The state machine -- waits for the data sender to acknowledge that it knows the data -- has been read. This is indicated when the in_ready signal is -- deasserted when read_in3=> if( in_ready='0' ) then next_state <= read_in4; elsif( in_ready='1' ) then next_state <= read_in3; end if; -- read_in4 is the final handshaking stage. The state machine -- deasserts the read_done signal, so the data sender can put new -- data on the input bus. when read_in4=> read_done <= '0'; next_state <= your_next_state; For output use : -- write_out1 is the first stage of handshaking. The value of the -- write_out line is checked to see if data may be put on the ouptut bus. when write_out1=> if( write_done='0' ) then next_state <= write_out2; elsif( write_done-'1' ) then next_state <= write_out1; end if; -- write_out1 is the second state of the output hanshaking. Put the -- data on the output bus, and assert the write_out to indicate that -- it is valid data when write_out2=> output <= out_data; --output corresponds to the output ports of your --machine. out_data is the data being sent to data --consumer. out_ready <= '1'; next_state <= write_out3; -- write_out3 is the third stage of handshaking. When the data -- receiver asserts the write_done signal to indicate that it has -- read the data, the state machine may continue. when write_out3=> if( write_done='1' ) then next_state <= write_out4; elsif( write_done='0' ) then next_state <= write_out3; end if; -- write_out4 is the fourth stage of the handshaking. The state -- machine acknowledges that the data has been read by deasserting -- the write_out line. when write_out4=> out_ready <= '0'; next_state <= your_next_state;