Table of Contents

 

  1. StateCad
  2.  

  3. Time and Size
  4.  

  5. Hint for using ACTmap
    1. Procedure
    2. Multiple Event
    3. Wait and Delay
     
  6. Error Message
    1. Trouble after ACTmap
    2. Graphical characters
    3. Designer: syntax error
    4. Script file for qhsim
     
  7. Efficient VHDL code under ACTmap
    1. If VS Case
    2. If VS Case VS Type
     

    In the course of design, we are exposed to many different kinds of tools that help to develop your design more efficiently and effectively. Throughout this project, we have learned and gained a lot of experience, especially using actmap and designer. In this CAD Tool document, we would like to take this opportunity to share our experiences so that students who take this course in the future would benefit and save more times.

 


1. StateCad

When we start our design, we have so many ideas. If we start to code our design right away, this would lead to so many design errors. Then, we start to draw our state diagram. However, if our design is large and involves many states, drawing it out would take a lot of time. Fortunately, we discover that there is a shareware called "StateCad" that really helps design a lot and reduce a lot of headache.

StateCAD automatically translates bubble diagrams into synthesizable VHDL, Verilog, ABEL-HDL, Altera-AHDL, and C. Variables, port definitions, and sensitivity lists are automatically created for all state machines and associated logic. Because state diagrams are precise and unambiguous, the resulting HDL is error free and exactly represents your specification. Revision becomes simple, just fix the graphical diagram and re-compile to update the HDL.
 

The following example shows how easy and user-friendly "StateCad" is:

When you finish drawing all the state, just goto File Menu and select HDL Output. Then, it will translate your state into VHDL code. EASY!

If anyone want to download a copy, http://www.statecad.com



 2.  Time and Size
Before you decide your project, try always to keep two things in mind: time and size. You cannot be too ambitious and remember that you will only have a 547-modules FPGA with 57 user I/O pins at maximum. At this point, we think you will ask what is that 547 modules mean? In our case, we are building a Smart Home Security System (For details, please look at Final report). The following summarizes some statistics:

 
 
Module Name Area (modules) Line of VHDL code
Door Checker 0 32
Switch Decoder 8 62
LCD Display 168 278
Password Checker 174 314
Main Controller 161 317
Monitor 21 174
Total 532 1177
 

Not much! Only 1177 line of code would take up about 97% of the ACT™ 1 FPGA. Therefore, you should think of something reasonable. If you are still not sure, then here comes another important factor "Time". Start your project NOW and finish it early. Then, use "actmapw" to determine the size of your project.

 

    (at the shell, type)

    % actmapw &

  1. In the File Menu, choose NEW, select your filename.vhd and press ok.
  2. Under ACTmap VHDL Compile, select
    1. Map Style : area
    2. Family : ACT 1
    3. Mode : chip
    4. Effort : mid
    5. Max Fanout : 16
    6. Flatten : yes
  1. Press RUN
 
After a few minute of compiling, (hopefully no error message), it converts your VHDL code into EDN format for "designer" use. At the message box, you will find out the size of your project or individual particular module. If it turns out that your project is too large, you still have time to cut feature down and modify.

 

Later, in the simulation process or back-annotated simulation with extracted delay, you will strongly find that time is the only factor that will make your project success. The reason we say this because "actmap" and "designer" have many constraints on VHDL codes. If you encounter an error and don?t know how to fix it, trial and error is the only solution and this actually helps. Later, we will discuss some errors we meet and how to get around with them.

 


3.  Hints for using ACTmap
     

    Procedures

    When using procedures, ACTmap VHDL requires the use of intermediate signals. If you have a procedure, the following example will not work:

            LCD_procedure(initialize(data));

    Add an intermediate signal and try to the following example:

            Temp <= initialize(data);

            LCD_procedure(Temp);

    Multiple Event

    If ACTmap complains you with 2 clock, you may probably have 2 or more events within one process. Try to have one event with one process.

     
    The following example won't work:

    process(clock,reset) begin

        if rising_edge(clock) then

            if rising_edge(reset) then

                ...

                ...

            end if;

        end if;

    end process;
     

    Modify the code and make reset become one of your states.

     

    change_state : process(clock, reset) begin

    if rising_edge(clock) then

        if reset = '1' then

            state <= reset_state;

        else

            state <= next_state;

        end if;

    end if;

     

    state_machine : process(reset, ... ,)

    case state is

        when reset_state =>

            ...

         when A =>

            ...

          end case;

    end process;
     

    Wait and Delay

    Do not use wait or delay statements in your VHDL code. ACTmap will not be happy and gives error. The only solution is to explicitly increment a time counter. Please look at Efficient VHDL code under ACTmap for details



    4.  Error Messages
 

Troubles after ACTmap

 After you have used ACTmap to generate the .edn file, the chance of likely your file cannot be compiled under designer architecture is very high. It is because ACTmap has added a few characters in the beginning of your VHDL code. Therefore, I recommend that always save your files a second copy (with different names) and use only one copy for ACTmap and use another copy for modification purpose.

 

The error message will read something like this:

ERROR: near "(" syntax error

ERROR: Quickhdl compilation failed -1-

 

Graphical Character

 After you have coded your project at home, you download it into your account. Later, you start to run your files and compile under ACTmap. Then, strange things happen. This time, ACTmap complains you that your have many "Graphical Character" in your program at some line numbers. However, at these line numbers, you don't see any special characters. Then, you start to be panic and no helps. (This is somewhat similar to my feeling at that time.)

 At this time, you have two possible choices. One, re-type the whole program using da and save it with different name. Compile it, again. I believe that this time, ACTmap will not give you the same error messages again (may be some new one :)  ) This approach work, but is tedious and very time-consuming. However, we have a better one. We think that from our experience, the reason for this "graphical character" error message is that in the process of transmitting files, some special forms of characters have added to the end of each line. That's why ACTmap reads this special character as "graphical character". This can easily fix using vi editor. (I take lot of time to figure out this) When you open vi editor, type vi at the prompt.

 

    % vi filename.vhd

(Don't worry if you don't know how to use vi)

You will see your filename like below:

     library ieee;^M

     use ieee.std_logic_1164.all;^M

     entity ABC ^M

     port ( ... )^M

     architecture behavior of something is^M

     begin^M

         process( ...)^M
                statement;^M

        end process;^M

     end behavior;^M

 You whole file has been corrupted with ^M at the end of each line. Then, use your arrow key to go to the ^M position and press x (stands for delete thing at cursor). After you clean up the whole file and run it again using ACTmap. This time, no more "graphical character" error message. Similar idea can be applied if ACTmap or da complains you with some character, which is not inside your file. Try it.

 

ERROR: Designer : syntax error

 After you have converted your file from edn format to VHDL format, you begin to simulate the structural VHDL. If you compile, compiler gives you error message like "Designer: syntax error", this is probably that you have missed the path. Try the following step.

 

  1. Quit design architecture (da)
  2. Go to the directory that contains your structural VHDL
  3. % setenv MGC_WD `pwd`
  4. % setenv QUICKHDL /opt1/actel/lib/vtl/95/qhdl/quickhdl.ini
  5. % ln -s $QUICKHDL .
 

After the above steps, starts design architecture again and re-compiles the structural VHDL file. Hopefully, it doesn?t give you any error.

 

Script File for Qhsim

 

When you start simulation, a small change to your VHDL code would need to compile the file again and simulate it again. This requires you to bring up all the signals and initialize them again. Running script file would really help you a lot and save you much time. The following example shows how to write a script file for qhsim:

 

  1. Open a text editor
  2. Wave any signal that you want to view, for example
  3. wave A

    wave B

    wave clock

  4. Force the value to the signals
  5. force A 0

    force B 1

    force clock 0 100, 1 200 -r 200
     

  6. save file the same directory as your VHDL code. In this case, we pick a name "init"
 

In the qhsim.mod window, type "do init". This will initialize your waveform and save you a lot of time.

 

Hints for working with back-annotated simulations

 

We believe that when you are back annotated your design the first time, the chance for your project will work perfectly similar to behaviour simulation is very unlikely. However, don't be panic. Everyone experiences this. Just a reminder that most significant bit (MSB) and the least significant bit (LSB) are reversed. After you recognize this difference, test your design again. If it is still not working, then you have to use step by step approach to debug your program.

 

Three more hints

 

  1. If you know how to use "structure window" under qhsim, then bring up all the ff_state_signal to your state machine and follow it from the beginning and walk thru the simulation to see where things go wrong and fix them. If you find all the ff_state_signal to your state machine, add those signals to your script file that described above. It really saves much times if we don?t have to look for the ff_state_signal every time.
  2.  

  3. If you are not familiar with the "structure window", then try to use some of your output pins to output the signals of your state machine. It works the same as above. This why I say in the beginning of the CAD Tool Document, time is a important factor to make this project work. Trial and error and debug your project. Have fun.
  4.  

  5. Explicitly state the value of each signal inside your state machine. Don?t leave qhsim to determine the values to your signal.
 For exmple:
 

        when A =>

            load_a <= '1';
            s <= "000";
            next_state <= B;

        when B =>

            s <= "011";

        next_state <= C;

            ...

In this case, don't assume at state B, load_a will still remain a value of '1'. Explicitly state it. Therefore, should     change to

        when B =>

                load_a <= '1';
                s <= "011";

        next_state <= C;

                ...

This way, you will guarantee your output.

 


5.  Efficient VHDL code under ACTmap
 

In this course, we have done many things to minimize the modules by actually using different ways to program the same code. Results turn out that actmap doesn't really like the "if " statement, if massive "if" statements have used, this would take lot of modules. See example below:

 
entity timer is
        port (clock, timestart : in std_logic;
                time_is_up : out std_logic);
end timer;

architecture time of timer is

begin

    timer_logic: process(clock,timestart)
    variable timecounter : integer := 0;

    begin

    if (clock = '1' and clock'event) then

        if timestart = '1' then

            if timecounter < 30 then

                timecounter := timecounter + 1;

            elsif timecounter = 30 then

                time_is_up <= '1';

            end if;

        elsif timestart = '0' then

            timecounter := 0;

            time_is_up <= '0';

        end if;

      end if;

    end process;

end time;

 
This example demonstrates a 30 second-timer (for simplicity, assume the input clock in 1Hz). This timer will generate a pule for "time_is_up" when 30 seconds have reached. In this case, we only use "if" statement in this simple program to show how complex this example can be. The following is the recorded result under ACTmap using "area" option for map style, "block" mode, no flatten, "med" effort and max fanout = 16.

 

Report results

Final Estimated Results

File: t1.edn

Comb. Modules: 131 modules

Area: 197 modules

Longest Path: 191.7 ns

Max Levels: 18

IO Pins: 3

Clk Networks: 1
 

A simple counter will take 197 modules. Amazing!



In version 2, we have tried to change most "if" statement into "case" statement.

 

entity timer is
        port (clock, timestart : in std_logic;
        time_is_up : out std_logic);
end timer;

architecture time of timer is

begin

        timer_logic: process(clock,timestart)
        variable timecounter : integer := 0;
        constant timelimit : integer := 30;

        begin

        if (clock = '1' and clock'event) then

            if timestart = '1' then

                timecounter := timecounter + 1;

            else

                timecounter := 0;

            end if;

            case timecounter is

                when timelimit => time_is_up <= '1';

                    timecounter := 0;

                when others => NULL;

            end case;

        end if;

    end process;

end time;

 
Same compile conditions have been used as above. The result is:

 

Report results

 

Final Estimated Results

File: t2_w_case.edn

Comb. Modules: 127 modules

Area: 193 modules

Longest Path: 291.3 ns

Max Levels: 30

IO Pins: 3

Clk Networks: 1

 

This time, there are only 6 modules different from the above result. Not very much!. The reason is because in this example, only one or two "if" statement has been reduced. If more "if" statements are reduced, this reduces the complexity of your program in compiler sense (at lease, it works for ACTmap). As a result, it reduces the numbers of modules.

 

See the next example for further reduction in area.



Throughout the experience of trial and error, we find out that not only "case" statement would generally reduce the area of logic modules, but also creates your own "type" would be useful, too. The following example shows a significant reduction in modules if you create your own type.

 

entity timer is
    port (clock, timestart : in std_logic;
        time_is_up : out std_logic);
end timer;

architecture time of timer is

    type number is range 0 to 31;

    begin

    timer_logic: process(clock,timestart)

        variable timecounter : number := 0;
        constant timelimit : number := 30;

        begin

            if (clock = '1' and clock'event) then

                if timestart = '1' then

                    timecounter := timecounter + 1;

                else

                    timecounter := 0;

                end if;

                case timecounter is

                    when timelimit => time_is_up <= '1';

                            timecounter := 0;

                    when others => NULL;

                end case;

            end if;

     end process;

end time;

 

Same compile conditions have been used as above. The result is:

 

Report results

 

Final Estimated Results

File: t2_w_type.edn

Comb. Modules: 22 modules

Area: 34 modules

Longest Path: 73.8 ns

Max Levels: 7

IO Pins: 3

Clk Networks: 1

 

In this example, we have used "type" and "case" statements together. Results have shown a tremendous reduction in area. 159 logic modules reduce. Pretty Amazing The reason for this reduction because ACTmap only uses 6 flip-flops as opposed to 33 flip-flops in the above examples.

 

One final general comment, start EARLY and don't be too ambitious in project design

Have Fun!

email: dkwok@gpu.srv.ualberta.ca