ws
Shared by: xiaopangnv
-
Stats
- views:
- 5
- posted:
- 10/20/2012
- language:
- English
- pages:
- 52
Document Sample


Simulation
Exercises
Dr. E.Kazanavičius
DK1 Tour
Write Handel-C
Build for Simulation
Simulate
Build for EDIF
Aim
To become familiar with using the DK1 Design Suite to build and simulate
a Handel-C project.
What to do
In this exercise you will compile and simulate some predefined Handel-C
source code, with the aim of becoming familiar with the operation of the
DK1 tools, and of seeing the language in action.
The example you will use is a simple 4-bit shift register, complete with
test stimulus for simulation.
What to do
Detailed instructions for completing this exercise are in the separate Celoxica
DK1 Design Suite Simulation Tour document. Work through the instructions in that
document, up to the section headed "Exiting".
You should do the following (please refer to the Tour for detailed instructions):
1. Create a DK1 Project.
2. Add the following file to the project
exl/shiftreg.hcc
The source code is listed opposite for reference.
3. Build (i.e. compile and link) the project for debug (i.e. simulation).
4. Simulate the project.
5. Using the DK1 debugger, inspect the simulation results.
When you have successfully run the simulation and explored the features of
the DK1 simulator, you might also like to experiment by modifying the shift
register design.
When you have finished, go straight on to exercise 2.
This is the Handel-C source code from the file shiftreg.hcc.
This is the Handel-C source code from the file shiftreg.hcc.
// A simple Handel-C model - shift register
set clock = external "Dummy";
void main (void)
{
// Declarations
unsigned 4 SR;
unsigned 1 Serial_in;
unsigned 1 Stop;
unsigned 8 i;
// Initialize simulation
Stop = 0;
// The stimulus and the shift register run in parallel
par{
// Stimulus
{
Serial_in = 1;
for (i = 0; i < 12; i++ ) {
;
}
Stop = 1;
}
// The Shift register
while (!Stop)
SR = SR[2:0] @ Serial in;
}
}
Exercise 2 (Practical) BCD / Integer Conversions
Write Handel-C
Build for Simulation
Simulate
Build for EDIF
Aim
To convert s,ome ISO-C code to a Handel-C model and learn about some of the
syntactic differences between the two languages.
Background:
Binary coded decimal (BCD) is a way of storing decimal numbers using a binary
code. Each decimal digit is stored as a separate 4-bit binary number. For
example, 5310 is stored as 010100112.
BCD is a useful format in applications where a decimal display is required instead
of a hexadecimal or binary one. A stopwatch is an example of such an application
(lap times are not usually measured in hex!)
What to do
1. 1.Have a look at the ISO-C code in the files ex2/bcd.c. The main function contains a
loop that calls two functions (bcd2int and int2bcd) and increments a BCD counter. Don't worry
about the details of the decimal to BCD conversion - this is an algorithm which, with the help
of Handel-C, we are going to implement in hardware.
2. 2.Compile and run the file bcd.c as a C program. For Microsoft Visual C++ the
commands are
this:
c:
cd c:\training\ex2,
get bcd..c –o
To run the resulting program, type this command:
\bcd.exe
3. Now translate the ISO-C to Handel-C. You might like to start with the main function and
bcd2int, leaving int2bcd until later.
4. Create a new Handel-C project and build the Handel-C version of the code for Debug (i.e.
simulation). If you make any syntax errors, you will of course have to correct them before you
can simulate. (You will be doing very well if you manage not to make any errors.) Simulate the
Handel-C model. Refer back to the Tour booklet to remind yourself of the instructions for using
DK1.
5. If you left the second function - int2bcd - have a go at translating it too. Using the
simulator, make a note of how many clock cycles it takes to run the int2bcd function.
Hints
In the C program bcd.c, the function bcd2int is declared like this
int bcd2int(int bcd[]);
In Handel-C, you will have to use pointers like this...
unsigned int 8 bcd2int(unsigned 4 *bcd);
Note: this doesn't make any difference to how you call the function, as an array name can be
given as an actual argument to a pointer (known as "array pointer equivalence" in C).
If You Have Time
The function int2bcd as written expects an integer value that fits in just two BCD digits.
Make the function more flexible so that it can cope with larger values. You will need to
widen the input / and modify the algorithm ccordingly.
Exercise 3 (Practical)Counters
Write Handel-C
Build for Simulation
Simulate
Build for EDIF
Aim
To practice writing an efficient Handel-C simulation model and some test
stimulus.
What to do
In this exercise you will write a Handel-C function to increment a decade counter. You will also
write a test to exercise the counter.
1. Write a Handel-C function to the following specification:
• The function is passed two 4 bit integers, each of which which contains a BCD-encoded
value. The first parameter's four bits represent the least significant digit; the other
parameter's four bits represent the most significant digit. On each clock cycle the least
significant digit is incremented. However, if the least significant digit is 910 (10012), the
digit rolls round to zero and the most significant digit is incremented. Hence the two
digits give a decimal counting sequence: 00, 01, 02, 03, ... 08, 09, 10, 11, 12, ..., 97, 98,
99,00,01,...
• The function is also passed an input Hold that, when asserted, causes the function to
leave the BCD-encoded value unchanged.
• The function should take exactly one clock cycle to execute, whatever the input values.
• Because the digits are modified by the function, they have to be passed by
reference,(using pointers).
2.Write a Handel-C main function that calls the counter function once per clock cycle and
provides some test stimulus. The main function should also count the number of clock cycles to
help you to check that the counter function always takes exactly one clock cycle.
3.Compile and simulate your model, taking care to check that it is working exactly according to
the specification. (If you are not sure how to do this, ask the course instructor for help.)
Exercise 4 (Practical) ALU
Write Handel-C
Build for Simulation
Simulate
Build for EDIF
Aim
This exercise uses many important features of Handel-C. The
main aims are (1) to practice using channels to communicate
between two processes; (2) to refine a model so that appropriate
actions are performed in parallel. You will also practice using the
arithmetic and logical operators to describe hardware.
Part 1
Write a process to describe an ALU that has the following
interface:
Name Type Description
A, B 8-bit signed Data inputs
Op Enum Opcode (see table)
F 8 bit signed Data output
Gout 1 bit unsigned Carry output
The type of Op is an enum, which defines meaningful names for the operations.
The operations are shown in the table below. The table also shows the binary
codes to be used for the operations when the ALU is synthesized. Note that there
are only 13 operations in the table; the codes do not form a binary sequence.
Enumeration Operation Code Gout F7 F6 F5 F4 F3
F2 F1 F0
AplusB A+ B "0000"
AminusB A-B "0001"
BminusA B-A "0010"
Cout F
OnlyA A "0100" A7 A7 A6A5 A4 A3A2A1Ao
OnlyB B "0101" B7 B7 B6 B5 B4 B3 B2 B1 B0 8 7 6 5 4 3 2 1 0
MinusA -A "0110" A7 A 0
MinusB -B "0111"
ShiftleftA shift left A "1000" A7 A7 A6A5 A4 A3A2A1 0 0 0 A
ShiftrightA shift right A "1001" 0 0 A6A5 A4 A3A2A1 A0
A7 A A7
RotateleftA rotate left A "1010" A7 A6A5 A4 A3A2A1 A0 A7
RotaterightA rotate right A "1011" 0 A0 A7 A6A5 A4 A3A2A1
ALLZeros F= 0 "1110" 0 00000000 0 A0 A
ALLOnes F = -1 "1111" 1 11111111
The shift operations are logical shifts, shifting A one place left or right and
setting the vacated bit to zero. Shift left moves bit 7 into Cout. Rotate left
moves bit 7 to both bit 0 and to Cout. Rotate right moves bit 0 to bit 7 (see
the diagrams above).
For all operations except shift and rotate, the inputs A and 6 are interpreted
as signed (twos complement) 8 bit numbers, and the result is a signed 9 bit
number. The lower 8 bits of the result are assigned to F, and the 9th bit of
the result is assigned to Cout, which is effectively the sign bit. If the result of
an arithmetic operation is negative, then Cout will be set.
For the undefined opcode values, F and Cout should be set to 0.
Initially, you should not worry about how many clock cycles the ALU uses.
This will be dealt with in part 2.
Write a simple test for the ALU as a separate process. The test process and
the ALU should communicate with each other using a single bit channel:
The test process should set up values for A, B and Op and send a '1' to the
ALU to indicate that a test is ready to run. The ALU should signal (using the
same channel) when it has calculated the corresponding values of F and
Cout. The test process can then set up a second test in the same way. If the
test process sends a '0' to the ALU, this indicates that there are no more
tests. The ALU should stop operating and the simulation should end.
Here are some test values you might like to use
A B Op F Cout
1 2 AplusB 3 0
2 3 Aminus B -1
127 1 AplusB 0 1
-128 0 slA 0 1
Part 2
Refine the ALU model so that it takes exactly one clock cycle to
calculate the values of F and Cout. You will need to remove the channel
to achieve this, because writing to or reading from a channel takes one
clock cycle.
Don't forget to make sure the test stimulus is applied at the appropriate
speed.
Write the simulation results (the values of F and Cout) to a file. Each line
in the file should contain 9 bits of binary data, being the concatenated
values of F and Cout.
Exercise 5 (Practical) FIR Filter
Write Handel-C
Build for Simulation
Simulate
Build for EDIF
Aim
To describe a pipelined design.
Background
An FIR filter accepts a series of digital samples over a number of clock cycles, and
transforms them according to the equation:
H(z) = C0z0 + C1z-1 + C2z-2 + C3z-3 + C4z-4 + C5z-5 + C6z-6
C0 to C6 are fixed coefficients. z0 through to z-6 represent the values of 7 consecutive input
samples. Thus, each output sample is a summation over 7 consecutive input samples,
each input sample being multiplied by a particular coefficient.
Each output sample is calculated from the previous 7 input samples. Each of those 7 input
samples is multiplied by a different coefficient, and the seven products are then summed.
This requires 7 multiplications and 6 additions per output sample. It is possible to do these
calculations in parallel for different output samples. For example, while the first input
sample is being multiplied by C2, the second input sample can be multiplied by C1 and the
current input sample can be multiplied by C0.
If the implementation contains 7 multipliers, then the FIR filter should be able to consume
samples at the rate of one per clock cycle. Make sure that the input and the output of the
filter is sampled at the same rate, i.e. one sample per clock cycle.
An easy way to code this algorithm is to shift the input data into a 7 stage shift register,
then calculate each output sample from these 7 stored input samples and the 7 coefficients.
What to do
Write some Handel-C code to describe an FIR filter with a length of 7 and a
word size of 8 bits (signed). Use the following coefficients:
54, 64,-7,-16, 15,-3,-7
Test the filter by applying some data. A suitable test is a square wave input; the
data input should be 0 for a few clocks, then go to 127 for a few clocks,
repeating this pattern three or four times. Write the output data to a text file,
firout.txt.
What to do
Use the plotting program
gnuplotio view the output data as
a waveform.
Run gnuplot by typing
gnuplot
and then at the gnuplot prompt
type
load 'plot‘
(The single quotes are
important.)
You should end up with a graph
similar to this.
Exercise 6 (Practical)
Seven-Segment Decoder
Write Handel-C
Build for Simulation
Simulate
Build for EDIF
Aim
Use functions or macros to describe a
duplicated circuit.
Seven-Segment Display and Decoder
A seven-segment decoder is a combinational circuit that takes a four bit
binary (or BCD) value and generates the signals to display the
corresponding digit on a seven-segment display.
What to do
1. Write a function or macro procedure to model a seven-segment
decoder. The input should be an unsigned four bit value and the
output an unsigned seven-bit value. The least significant bit
represents segment a and the most significant bit segment g. You
should assume that the polarity of the display is positive, so that a '1'
lights up the corresponding segment.
2. Copy the decade counter from exercise 3 and add a two digit seven
segment display to the
output.
3. Build and simulate the design. To help with this, a C++ function
printDisplay is provided in the
file ex6\printDisplay.cpp. Look in this file for details of how to use the
function.
4. You'll also need to use a custom build to build the file
printDisplay.cpp - your course tutor will
help with this, and it is also documented in the tool tour.
5. The printDisplay.cpp function assumes that the characters 6 and 9
do not have "tails", i.e.
Exercise 7 (Practical)
Hardware Interface and Download
Write Handel-C
Build for Simulation
Simulate
Build for EDIF
Aim
To take a design through the complete design
flow from Handel-C to configuring a real FPGA
and running it on a development board.
What to do
1. Make a copy of the decade counter with the seven segment display
drivers from exercise 6.
2. The Celoxica RC100 development board has an 80MHz clock and
the Altera Nios development board has a 33MHz clock. At these
speeds the seven segment displays will change too quickly for the
values to be visible. Add a counter to generate a Hold signal that is only
disserted once every 0.5 sec or thereabouts. Don't try to simulate this,
because you would be waiting a very long time for the simulated
display to do nothing.
3. Do not delete the simulation code; use the preprocessor directive
#ifdef so that the DK1 compiler knows which lines to compile for
EDIF or for simulation (Debug). The macros SIMULATE and
DEBUG are both defined for debug mode build; they are not defined for
EDIF mode build.
What to do
4. Add the appropriate device family for the development board you are
using in the Handel-C code or the Project Settings. This will be Spartan II
for the Celoxica RC100 board or APEX 20KE for the Altera Nios board.
5. Add a hardware interface. The names of the clock pins and of the pins
to drive the seven segment displays on the development boards are given
opposite. Segment 1 is the left hand display - it displays the most
significant digit. Note that in each case there is an eighth segment ("h"):
this drives the dot at the bottom right of the digit display and should be
turned off. Note also that the Altera NIOS board display inputs are active
low, whereas the Celoxica RC100 board display inputs are active high. In
addition, the RC100 displays must be enabled explicitly. The enables are
active high.
6. When you have finished editing the Handel-C code, build the project
for EDIF.
Celoxica RC100 Board
Chip: Xilinx Spartan II xc2s200-6fg456
Clock pin: A11 (80 MHz)
Display pins:
h g f e d c b a Enable
Segment 1 AA14 AA20 W18 Y18 V17 W14 AB14 V13 AA22
Segment 2 Y13 AB20 AA19 W17 AA18 AA13 AB13 W13 V20
Altera NIOS Board
Chip: Altera APEX 20KE EP20K200EFC484-2X
Clock pin: L6 (33.333 MHz)
Display pins:
h 9 f e d c b a
Segment 1 D18 V17 V18 Y17 V8 Y7 U11 R11
Segment 2 C18 W17 U18 Y18 W18 U8 T11 R10
Implementing the Design
You should now have an EDIF netlist suitable for implementing the
design using the Altera or Xilinx place and route tools. Once place and
route is complete, you should be able to download the design to the
development board and see the counter counting. Instructions for this
are specific to the place and route tools you are using:
For Altera Quartus II (for the Nios board)
For Xilinx ISE (for the Celoxica RC100 board)
Design Implementation Using Altera Quartus II (Nios Board)
1 . Start Quartus II using the Quartus II icon on the Windows desktop or
from the Start Menu.
2. After starting Quartus II, the first thing to do is to create a new
project. You may see the prompt "Do you want to create a new project
now?" in which case click on Yes. Otherwise Select menu File>New
Project Wizard... If the Wizard's introduction page appears, click Next.
3. In the Wizard, select the DK1 project EDIF subdirectory as the
working directory for the Quartus II project. Select a name for the
project and use the DK1 project name as the name for the top-level
entity. Click the Next button to move to the Add Files page. Add the
EDIF source file to the project and click the Finish button.
4. Now select menu Project>EDA Tool Settings... In the drop-
down list of Design entry/synthesis tools, select Custom and click
on the Settings... button. In the EDA Tool Input Settings dialog, browse
to find the Library Mapping File. This is located in the subdirectory of
the DK1 installation directory. (The default location is
C:\Program Files\Celoxica\DK1\lmf\handelc.lmf). Click the OK button to
close the dialog, and again to close the EDA Tools Settings form.
Design Implementation Using Altera Quartus II (Nios Board)
5. In the Quartus II Tel Console, which by default \s located in the
bottom right hand corner of the Quartus II aplication window, type the
following command:
source decade. tcl
(use the name of your Handel-C project). This loads the pin assignments
into Quartus II.
6. Select menu Processing>Compiler Settings... and in the Compiler
Settings dialog select the Chips & Devices form. Select APEX20KE as the
Family and the Specific target device EP20K200EFC484-2X (If you look at
the Altera APEX chip on the Nios demo board, you should see this exact
part number - you might need your reading glasses.) Click OK.
7. You are now ready to place and route the design. (In Quartus II
terminology this is called "compilation".) Either select menu
Processing>Start Compilation, or click on the icon for that function on the
toolbar. Compilation takes a few minutes to complete.
8. Whilst Compilation is running, you will see progress displayed in the
Status window, and also on the status bar at the bottom of the Quartus II
window. You will see messages appearing in the Messages window. An
alert box appears when processing is complete. Click the OK BT
button to dismiss it.
Design Implementation Using Altera Quartus II (Nios Board)
9. Once compilation is complete, you can view the Compilation report. (If the
compilation report is not already open, select menu Processing>Open
Compilation Report.) Look at the Summary and the Resource Usage
Summary in the Resource Section of the report, which tell you how much of
the device you've used, and how many logic elements, ESBs, flipflops etc.
You might like to compare this with the estimates from DK1. Look also at the
maximum operating frequency, fmax, in the Timing Analyses section of the
compilation report. The board runs at 33MHz, so the design needs to run at
33MHz or above.
10. You are now ready to download the compiled design to the Nios board.
First, make sure SW8 is in "Connect" position while SW9 and SW10 are in
"Bypass" position. (These switches are located next to the seven-segment
displays.) Connect the Altera ByteBlasterMV download cable to JP3,
making sure pinl (red mark on the cable) is correctly positioned.
Design Implementation Using Altera Quartus II (Nios Board)
11. In Quartus II, select menu Processing>Open Programmer to launch the
Programmer. You may be asked to set up the hardware: if so, select
Hardware Type: Byteblaster, Parallel Port: LPT1.
12. Click Add File... and select the .SOF file. Select the "Program/Configure"
option. Press the "Start" button. The configuration is downloaded and the
board should start operating: you should see the decimal count on the
seven-segment displays. If the board does not operate
JJH properly, the most likely explanation is that you have not specified
the pins correctly (Is the order correct? The polarity?)
Design Implementation Using Xilinx ISE (Celoxica RC100 Board)
1 . Start the Xilinx ISE Project Navigator, from the Desktop or from the Start menu.
2. First, you must create a project. Select menu File>New Project... and in the New
Project dialog browse to the EDIF subdirectory of the DK1 project directory. Type a
name for the project (e.g. Decade). Select the Family Spartan2, the Device xc2s200-
6fg456 and the Design Flow EDIF. Click OK. (If you look at the Xilinx SPARTAN chip
on the RC100 development board, you should see this part number, without the "-6";
you might need your &-,
reading glasses.)
3. Now select menu Project>Add Source... and in the Add Existing Sources dialog,
select the EDIF file generated by DK1 . Click Open.
4. Double-click on Generate Programming File in the Processes for Current Source
window. The design will now be implemented and a programming file generated; this
will take a few minutes to complete. When implementation is complete, expand
Implement Design, then Place & Route in the Processes for Current Source window
and double-click on Place & Route Report. Scroll down to find the Device utilization
summary and compare the figures with the estimates that DK1 gave earlier. Scroll
down further until you see the table of timing constraints. (This is near the bottom of
the report.)
Design Implementation Using Xilinx ISE (Celoxica RC100 Board)
5. The RC100 board operates at 80MHz, which means the clock period of the design
must be 12.5ns or less. If this constraint is not met, the display may not work
properly. If this happens,use a divided internal clock:
set clock = external_divide "All" 2;
6. You will also need to adjust the size of the counter that generates the hold signal.
Re-build the EDIF file in DK1 and generate a new programming file using the Xilinx
ISE Project Navigator (step 4 above). Check that the timing constraint is now met.
7. To download the programming file to the RC100 board, use the RC100 File
Transfer Utility, which may be launched from the Windows Start menu (or there may
be an icon on the Desktop). This utility is provided by Celoxica and is separate from
the Xilinx ISE software. Select FPGA from the device drop-down list and click
Write... Browse, select the bit file and click Open. The configuration is
downloaded and the board should start operating: you should see the decimal count
on the seven-segment displays. If the board does not operate properly, the most
likely explanation is that you have not specified the pins correctly (Is the order
correct? Is the polarity correct? Are the displays enabled?) Or the design is being
clocked too quickly: see the instructions in step 5 above.
Exercise 8 (Practical) Delay/Area
Estimation
Write Handel-C
Build for Simulation
Simulate
Build for EDIF
Aim
To understand how to interpret the delay/area estimates
from DK1 and compare with the values reported by the
place and route tools.
What to do
Using the Decade Counter example from exercise 7, generate the
delay/area estimate files from DK1. To do this, you will need to select
the options Generate estimation info and Use technology mapper in the
Linker tab of the Project Settings dialog and build for EDIF.
Using a web browser, open the file EDIF\Summary.html, which contains
the area and delay estimates.
Write down the estimated number of lookup tables (LUT), flip-flops (FF)
and (Xilinx only) Other.
Write down the estimated flip-flop to flip-flop and flip-flop to output
delays. The Altera NIOS board contains a speed grade 2 APEX 20KE
device. The Celoxica RC100 board contains a speed-grade 6 Spartan II
device.
Implement the design in the Altera or Xilinx place and route tools
(although you did this inexercise 7, the Technology Mapper was not
turned on. The results may be different). Using the place and route
tools, find out the area and timing of the implemented design and
compare these figures with the estimates from DK1.
Exercise 9 (Practical)
Seven-Segment Display Plugin
Write Handel-C
Build for Simulation
Simulate
Build for EDIF
Aim
Simulate a design using a simulator plugin.
What to do
Interface the decade counter (exercise 7) to the simulator's
plugin seven-segment display. The plugin will need to be
referenced twice, once for each 4-bit BCD output. For
simulation, you will need to bypass the part of the counter
that was included to slow the clock down, because the
simulation will run much more slowly than the
development board. You may need to experiment to see
how big a counter you still need.
Run the simulation. The two seven segment simulation
displays may appear with one on top of the other - use a
mouse to move the top one.
Exercise 10 (Practical)
Bubblesort
Write Handel-C
Build for Simulation
Simulate
Build for EDIF
Aim
Run simulations of designs containing both Handel-C and C++
source code.
Bubblesort Algorithm
Bubblesort is a simple list-sorting algorithm, which repeatedly steps
through a list, comparing elements with each other and swapping them
if necessary. This results in low values "falling" to the bottom of the list,
and high values "rising" to the top of the list, hence the name.
In this exercise you will begin by implementing a bubblesort algorithm
in software and calling these software functions from Handel-C code.
Inline calls to ISO C functions will also be used.
The bubblesort will then be ported to Handel-C, and ISO C/C++
functions will be used to create functional testbenches for it.
The C++ source code for the bubblesort algorithm is in the file
ex10\software_bubble.cpp. (These functions are nominally C++,
because we shall later be using the HCNum class library. No other C++
features are used.)
What to do
1. Create a new workspace called bubblesort and inside it create a new
project named software_bubble.
2. Move the C++ source file ex10\software_sort.cpp to the project directory
and add this file to the project.
3. Set up a custom build step for this file as follows:
In the Project Settings dialog, select Settings for: Debug, select the file
software_sort.cpp and click on the Build commands tab.
Make sure that the View drop-down list is set to Commands, and click the
button to create a new command.
We can now enter the command required to use a backend C/C++
compiler to build the Source file for simulation. For Microsoft Visual C++,
the command is:
cl /I C:\AppsCeloxica\DKl.lSPl\Sim\Include /c $ (InputPath)/Fo$ (TargetDir) \$
(InputName) .obj
(all on one line)
What to do
The tool, cl in this case (Microsoft Visual C++), could be replaced
with one of the other supported C/C++ compilers. The include
path must be set to wherever DK1 is installed on your computer -
this may be different from the example shown above. In this
example, we have used the S(lnputPath) macro to specify the
source file. DK1 will substitute the name of the source file for this
macro when it executes the command. The /Fo setting for cl
allows us to specify where the output object file will be written. In
this example, we have used another macro, $(.TargetDir), which
will be substituted with Debug or Release, depending on which
configuration is active, and the macro $(lnputName) which returns
the name of the file without the extension. By using these macros,
we can now re-use this build command with any C++ source file.
A similar command could be used for C files, simply by changing
the source extension from .cpp to .c.
What to do
Having specified a build command, we must also specify the output
resulting from its execution, as DK1 will check the timestamp on this
output to see if the build step needs to beexecuted. Still in the settings
for the C/C++ source file, select Outputs from the View drop-down list,
and click the New button again. The output should be the same as that
specified in the actual build command, in this case:
$ (TargetDir) \$ (InputName).obj
Again, we use the macro names so that the same output definition can
be used for any C/C++ source file. Note that you must specify an output
for the build step, or it will nor be executed. DK1 will warn you of this.
What to do
4. Having created a C++ source file, and specified a custom build step for
it, we can now add a Handel-C source file to the project. The C++ functions
will be called from the Handel-C main function. The Handel-C code is
provided in the file ex10\main.hcc. Add this file to the project.
5. The simulator will execute the C++ functions in zero clock cycles, so
single-cycle delay; statements have been added between the calls to the
functions, to allow us to step through the code in the simulator and observe
its operation.
6. Before we can build the project for simulation, we must tell DK1 where to
find the C/C++modules to link in with the Handel-C code. Open the Project
Settings and select the Linker tab. The relative path of the object file(s)
produced by the custom build step(s) must be added to the Additional C /
C++ Modules box. In this case, there is only one object file enter its' path as
Debug\software_sort.obj.
What to do
7. Click the Build button, or select Build->Rebuild All, and the project will
be built for simulation.
8. Step through the simulation, one cycle at a time (press F11 to do this).
The calls to prinff will be written to a Command Window (DOS box) as the
simulation runs. The calls to the C++ functions will be executed in zero
clock cycles, and the simulator will only stop on the delay
statements. Each time the simulator stops, you will see the
contents of the data array change in the Variables window. The
sw_init_data() function uses a random number generator to initialise the
array, so the contents of data will be different each time the simulation is
executed.
9. Write a Handel-C version of the C++ function sw_sort_data and call it
hw_sort_data. Take care to write the Handel-C code so as to generate
efficient hardware. Don't simply translate the C++ code line by line. Put this
function in a separate file, which you should add to the project. You will also
need to modify the main function to call hw_sort_data. Build and simulate
your design.
If you have time
Now change the width of the data to be sorted from 8 bits (the size of char)
to 12 bits. You will need to change the C++ functions to accommodate this.
If you still have time
The test for the bubblesort simply displays the sorted data in the command
window, allowing the user to visually inspect that the operation was correct.
However, in many applications this will not be possible. It would be better to
create an automated testbench to prove the functionality of the Handel-C
code, compared to the C++ version.
Modify the main.hcc file to contain 2 copies of the data array, and after
initializing one, copy its contents into the other, and then call both the
Handel-C and C++ bubblesort functions, passing the copy of data into the
C++ version.
Now write a C++ function to compare the results of the two different
bubblesort functions. The function should say whether or not the contents
of the two data arrays are the same. This function can be included in the
software_sort.cpp source file.
Exercise 11 (Practical) Memory
Write Handel-C
Build for Simulation
Simulate
Build for EDIF
Aim
Build a simple FIFO buffer to store a serial incoming
data stream and convert to parallel words. The main
FIFO memory will be stored in the on-chip RAM
available in Altera or Xilinx FPGAs.
What to do
The FIFO has three single-bit inputs, Start, Datajn and Read, and an eight-bit
output, Data_out.
Data_in
Data_out
Start
Read
Start is asserted for one clock cycle to indicate the start of a data word. At the
same time Datajn contains the first (least significant) bit of the data word. The
subsequent data word bits are placed on Datajn in the following 7 clock cycles.
When the complete word has been received, it should be stored in memory at
the next free location.
When Read is asserted, a data word appears on the output. A new word
appears in each clock cycle that Read is asserted.
Up to 256 words can be stored at any time. If the memory becomes full
(because data is arriving more quickly than it is being read), the previously
stored values that have not yet been read should be overwritten. If the memory
is empty (because data is being read faster than it is arriving), the output is
undefined.
What to do
In order to create the design, you will need to store internally the next
free memory location, and the location of the first unread data word.
Serial data should be read into an eight-bit shift register. When the
shift register is full (indicated by Sfart being asserted), its contents
should be written to the memory.
Build the project for Debug and simulate it to make sure it works.
Build the design for EDIF and check that the on-chip memory blocks
have been used: look in the Report window at the bottom of the DK1
application.
If time permits, place and route the design and make sure than on-
chip memory blocks have been used by the place and route tools.
Exercise 12 (Practical)
(FIFO with Multiple Clock Domains)
Write Handel-C
Build for Simulation
Simulate
Build for EDIF
Aim
Create a design with two independent clocks.
What to do
1. Copy the FIFO design from exercise 11 and modify it so that the serial
data has its own clock. The parallel output has a separate clock. To do
this, you will need two separate main functions, each with its own clock.
2. Simulate the design with the serial clock running eight times faster than
the parallel clock.
3. Build the EDIF file for the design and make sure that the design can be
implemented using the place and route tools.
If you have time
Use an Altera PLL or Xilinx DLL as an on-chip clock divider to generate
the parallel clock from the serial clock. First, you will have to modify the
two-clock FIFO design you have just created so that the two clocks come
from input ports (use portjn interfaces as internal clocks). Next create a
second project that instances the FIFO and a PLL or DLL to generate the
clocks; this requires two user-defined interfaces with signals to connect the
clocks. Build the projects to give two EDIF files and use the Altera Quartus
II or Xilinx ISE place and route tools as appropriate to implement the
design. The EDIF files (and the Altera .tdf file) should be copied to a
common directory.
Detailed instructions for using an Altera PLL and a Xilinx DLL are provided
after the diagram.
What to do
Altera PLL
In Quartus II, select menu Tools>MegaWizard Plug-In Manager...
On page 1, select Create a new custom megafunction variation and click Next.
On page 2a, expand Installed Plug-Ins and I/O and select ALTCLKLOCK. Create
an AHDL output file in the ex12 directory called divbyS.tdf and click Next. (AHDL
is Altera's proprietary hardware description language. If you have a VHDL or
Verilog license for Quartus II, you could generate a VHDL or Verilog file instead.)
On page 3, select the APEX20KE family, leave the other options at their default
values and click Next.
Altera PLL
On page 4, select an input clock frequency of 100Mhz and use the
ClockO output with multiplication and division factors or 1 and the Clockl
output with a multiplication factor of 1 and a division factor of 8. Click
Finish.
On page 6, click Finish.
Create a custom interface to the generated megafunction model at an
appropriate point in your Handel-C code. If you look in the generated
AHDL file (divbyS.tdf) you will see that the megafunction has an input
called inclock and outputs called clock0 and clock1. You will need to
ensure that the AHDL file divbyS.tdf is copied to the directory in which
the EDIF files were written.
Xilinx DLL
At an appropriate point in the Handel-C code, create custom interfaces
corresponding to the following Xilinx components:
• CLKDLL component (for Virtex or Spartan II) or CLKDLLE (for
Virtex-E).
• IBUFG
• BUFG
You will need one IBUFG, one CLKDLL or CLKDLLE and two BUFGs.
(Refer to the course manual for details.)
Add the following property specification to the CLKDLL:
with { properties = { { "CLKDV_DIVIDE" , "8"} } };
Build the EDIF netlist for the design and implement it using the Xilinx ISE
Project Navigator.
Get documents about "