For a thorough discussion of these coding issues, see Chapter 13 in "Understanding Behavioral Synthesis" by John Elliott.
Coding for behavioral compilation is often subtly different from common practices of Verilog or VHDL coding. In most cases the differences are actually adherence to behavioral coding rules that are good practice design rules that are less stringent for non-behavioral coding. The behavioral coding rules are:
On the other hand, the implication of this for scheduling can be profound. Take for example the following loop:
for (i=0; i<=31; i=i+1) begin : outer_loop Out1[i] = a0 * a1 + a2 * a3 - a4 + a5 + a6 * a7; for (j=0; j<=15; j=j+1) begin : inner_loop Out2[j] = b0*b1+b2*b3-b4+b5+b6*b7-b8+b9; end endThis loop has 9 operations (multiplies, adds, subtracts) contained within an inner loop of 16 iterations contained within an outer loop of 32 iterations that itself contains 7 operations. If the loop is unrolled it results in 4832 events that need to be individually scheduled. This will result in a huge amount of computation for the schedule operation, which means a long schedule run. If we keep both loops rolled the result is only 16 events to schedule.
So, why would we ever want to unroll a loop? Basically it is a throughput (latency) versus area issue. A rolled loop requires the smallest amount of real estate, but it costs the number of clocks used in the loop multiplied by the number of iterations of the loop to execute the loop. An unrolled loop schedules individual hardware for each loop iteration, but it executes the loop only once with the number of clock cycles of the operations contained within the loop.
Superstate fixed mode "changes the rules". While you write your design to follow a behavior, you may somewhat ignore the actual timing an adder, multiplier, or other function actually take (in terms of hardware clock cycles). Scheduling figures out how many clock cycles are actually required for a particular technology or architecture, and Behavioral Compiler "plugs in" those clock cycles.
This does not mean you can totally ignore clocks. For example: entering, exiting, and iterating in a loop takes a state transition in the FSM generated. Hence:
The benefit of this is that it gives you far more freedom to explore different technologies or architectures. A possible disadvantage is that because of the clock cycles superstate-fixed mode inserts, the RTL or gate level implementation may simulate differently from the simulation of the behavioral level. This can be overcome with proper testbench design..
unix% cd coding
unix% bc_shell | tee Log/coding.log
bc_shell > analyze -s -f vhdl thresh.vhd
bc_shell > report_design_lib work
bc_shell > elaborate -s thresh
bc_shell > create_clock clk -p 15
bc_shell > bc_check_design -io cycle
At this point, you will get an error if the design cannot be scheduled.
Use your favorite ASCII editor to view the file thresh.vhd which you will find in the VHDL directory. Compare the thresh.vhd file you analyzed and elaborated to the file below. Edit thresh.vhd and save it as thresh1.vhd .
-- This is to be scheduled in cycle fixed scheduling mode. -- 1. clock period = 15 ns -- As is, this will not schedule. Find the error(s) and fix. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity thresh is port( clk,reset : in std_logic; in1, in2 : in std_logic_vector(7 downto 0); threshold : in std_logic_vector(15 downto 0); out1 : out std_logic); end thresh; architecture vhdl of thresh is begin main : process begin reset_loop : loop out1 <= '0'; wait until clk'event and clk = '1'; if (reset = '1') then exit reset_loop; end if; alg_loop : loop while ( in1 * in2 > threshold) loop wait until clk'event and clk = '1'; if (reset = '1') then exit reset_loop; end if; out1 <= '1'; end loop; wait until clk'event and clk = '1'; -- added this wait if (reset = '1') then exit reset_loop; end if; out1 <= '0'; wait until clk'event and clk = '1'; if (reset = '1') then exit reset_loop; end if; end loop; -- alg_loop end loop; -- reset_loop end process ; end vhdl;Now that you have corrected and saved your design, clear the design from the Behavioral Compiler memory and run through the steps with the new design version.
bc_shell > remove_design -design
bc_shell > analyze -s -f vhdl thresh1.vhd
bc_shell > report_design_lib work
bc_shell > elaborate -s thresh
bc_shell > create_clock clk -p 15
bc_shell > bc_check_design -io cycle
If you completed the edit correctly, you will not get an error. If you do get an error, go back and make the necessary corrections and repeat these steps before proceeding with timing the design.
bc_shell > bc_time_design
bc_shell > report_resource_estimates > Reports/estim.rpt
bc_shell > write -h -o DB/thresh_timed.db
Examine the estim.rpt file and note the following:
What is the delay through the multiplier (*)? _____________
What is the chain delay through the multiplier (*)? ________________
What is the word level delay through the Comparator (>)? _________
This information will be helpful in understanding the following steps.
bc_shell > schedule -io cycle -effort medium
bc_shell > report_schedule > Reports/thresh_15ns.rpt
bc_shell > write -h -o DB/thresh_15ns_sch.db
bc_shell > bc_view
Observe the estimated area and latency of the design.
This tutorial section about coding styles stops at this point. If you are interested, you can go through these steps trying other clock periods such as 10ns to see the difference. You could also re-run the lab this time using superstate mode for the I/O mode. If you try further experiments, remember to save the scheduled db with a representative name such as thresh_10ns_sch.db and save your reports with similar names. Then you can do comparisons between the different runs.
This tutorial section briefly described the issues related to loops, conditionals, resets, cycle-fixed versus superstate mode, and other considerations of coding for behavioral compilation. It showed you the power of behavioral compilation over coding for targeted architectures and/or technologies. The Behavioral Compiler class covers these issues in detail.
On to Chapter 4 - Simulation