You are here:

Home Research HW/SW Co-Design COOL Case Study



Case Study: Fuzzy Controller

COOL was used during a student project to implement a fuzzy controller on a heterogeneous target architecture. The task of the fuzzy controller is to control the traffic lights at a certain crossing of a main street and a side street. This crossing contains three different lanes as depicted in the following figure.

The idea is to control the traffic lights depending on the number and the waiting time of cars in each lane. The goal of the fuzzy controller is to minimize the average latency of the cars. The principle functionality of the fuzzy controller is depicted in the next figure.

For each lane the fuzzy controller uses the same modules to compute an urgency metric to get the green-signal. To reuse the same modules for each lane allows to apply hardware sharing to minimize the total costs during the design process. The modules for each lane have the following inputs: the waiting time, the number of cars and a boolean value representing whether a pedestrian is waiting or not. Like most fuzzy controllers, these inputs (representing linguistic variables) are fuzzified in a first step computing linguistic terms for the inputs. Then, the inference applies some rules stored in a rule base to the linguistic terms. After this, the resulting values are defuzzified into discrete output values, here the urgency metric presented above. Finally, the lane with the highest value of this urgency metric gets the green-signal. First, the fuzzy controller was specified with COOL. The way of specifying systems in COOL is very well suited for this example, because the modules of the fuzzy controller can be specified by different system components which are instantiated for each lane afterwards. The resulting system specification consisting of 31 instances of 7 system components is depicted.

In total, the behavioral VHDL specifications consist of 900 loc (lines of code). The goal was to implement this fuzzy controller specification on a target architecture as depicted in the following figure. containing

  • a Motorola DSP56001,
  • an ASIC,
  • a 64kB memory and
  • a communication channel (connecting the DSP, the ASIC and the memory) consisting of an 8-bit data bus and a 16-bit address bus.

To validate the correctness of the resulting hardware/software system, the students developed a prototyping environment, using

  • a PC plug-in card from Davis containing the Motorola DSP56001 and a sandwich card for the Davis card to connect the DSP to the busses,
  • an FPGA-board with two Xilinx FPGAs 4005 (with 196 CLBs (Configurable Logic Block) and 61 available pins each) to implement the ASIC and
  • a memory board containing 64kB static RAM, additional bus drivers and RAM logic.

All these cards and boards were connected using an 8-bit data bus and a 16-bit address bus as depicted in the next figure.

The prototyping board looks as follows:

The main disadvantage of this prototyping board was the limited amount of hardware resources with 2x 196 CLBs and 2x 61 pins. Most of the specified components of the fuzzy controller could not be implemented on the FPGAs due to the lack of CLBs. To implement the fuzzy controller on the prototyping environment, the hardware/software partitioning was driven by designer defined mapping constraints resulting in the following hardware/software partitioning.

The computed partitioning consisted of 15 nodes implemented in hardware and 16 nodes implemented in software. Afterwards, all co-synthesis steps (generation and optimization of the STG, memory allocation, specification refinement, controller and netlist generation) were executed resulting in the netlist depicted in the following figure.

Then, the refined C specification for the Motorola DSP (961 loc) was compiled into assembler code (5305 loc) and into a binary file afterwards. The hardware parts implemented on the ASICs were partitioned into two separated VHDL descriptions (one for each FPGA) manually, because otherwise pin constraints were violated. The system controller and the I/O controller were implemented on the first FPGA, the bus arbiter, the hardware data paths and their controllers on the second FPGA. Then, both VHDL descriptions (1266 loc) were synthesized by Synopsys and afterwards the Xilinx tools generated the specific configuration files for the FPGAs. The result was a utilization of 80% for the first and 85% for the second FPGA. After this, the binary file for the DSP was down-loaded to the Davis-card using the PC and both FPGAs were configured by down-loading their configuration files from a workstation. At this time, the system could be started using a special simulation environment implemented on the PC generating the values for the inputs and visualizing the results of the fuzzy controller. The correct behavior of the hardware/software implementation was checked with the help of a logic analyzer which is very helpful to find errors in the design or on the prototyping board. Most importantly, this application study proves that the design flow of COOL results in hardware/software systems that are operational and that COOL represents a complete hardware/software codesign tool. Different alternatives of hardware/software partitions were implemented for the fuzzy controller and in all cases the time to execute the complete design flow from system specification to an implementation on the prototyping environment took not more than 60 minutes. The time-consuming factor was hardware synthesis consuming about 90% of the design time. Finally, the functionality of a netlist generated by COOL will be described with the help of the partitioned fuzzy controller (see figure). The simulated netlist itself is depicted in the following figure. In the following figure the results of executing co-simulation with COOL using Vantage Optium are depicted. The depicted part of the simulation illustrates the initialization phase and the computation of the first result computed for a set of input values. The main events are enumerated and will be described.


  1. The system is reset (reset <= '0') from the environment to be initialized.
  2. The processor and the hardware components are initialized.
  3. Some inputs change their value, but the system has not been started. Therefore no results are computed.
  4. The system is started from the environment (start <= '1').
  5. The system controller sends a message to the I/O controller to check if some inputs have changed (update_inputs <= '1').
  6. The I/O controller writes input values (which have changed) into memory.
  7. The I/O controller indicates to the system controller that input values have changed (inputs_changed <= '1').
  8. The system controller writes the execution state of the processor into memory.
  9. The processor is started by interrupt (irq <= '0').
  10. The processor reads its execution state from memory.
  11. The processor executes a set of functions until synchronization with the system controller is required. The computed results are written into memory.
  12. Concurrently to step 11, the system controller snoops the bus to detect the DONE-message written by the processor.
  13. The system controller has detected the DONE-message of the processor and changes the state-signal of the data path controller to "state <= 2" indicating to start execution.
  14. In addition, the processor is started again. Therefore, the system controller writes the new state into memory and sets the interrupt afterwards. Remark: now data path and processor work concurrently.
  15. The data path controller loads the input values i1 and i2 for the data path.
  16. The data path is started by the data path controller by start_dp <= '1'.
  17. The data path computes the result (o <= 4) for these inputs and indicates the end of computation to its controller by setting done_dp <="1" .
  18. The data path controller writes the computed result into memory.
  19. Then, the data path is started again...
  20. The processor is started for computing the last scheduled function by setting the interrupt.
  21. The bus snooper of the system controller detects the DONE-message of the processor.
  22. The I/O controller reads the computed result (256) from memory and transmits it to the environment.
  23. Now all steps (starting from step 4) will be repeated if some input signal changes its value.