As you learn VHDL, soon or later, you will do projects which require you to do operations on floating point(FP) numbers. In most of the programming languages, dealing with real numbers is as easy as dealing with integers. But not so in VHDL or Verilog.
If you want the design to be synthesisable, then the real numbers has to be stored in floating or fixed point format in hardware. Arithmetic operations on these numbers aren't so easy, if you have to write the code from scratch.
Fortunately, tools like Xilinx/Altera have IP's, which deals with these numbers. These IP's can be easily customized too. Xilinx grouped all these IP's under the CORE Generator system. In this post, I want to show you how to create a simple FP multiplier and how to simulate it.
Let's go step by step.
1) Create a new project in Xilinx ISE.
If you want the design to be synthesisable, then the real numbers has to be stored in floating or fixed point format in hardware. Arithmetic operations on these numbers aren't so easy, if you have to write the code from scratch.
Fortunately, tools like Xilinx/Altera have IP's, which deals with these numbers. These IP's can be easily customized too. Xilinx grouped all these IP's under the CORE Generator system. In this post, I want to show you how to create a simple FP multiplier and how to simulate it.
Let's go step by step.
1) Create a new project in Xilinx ISE.
3) Next select source type as IP(CORE Generator & Architecture Wizard). Enter the file name, and change the file location if needed. Click Next.
4) A new window will open up saying creating selector for specified device. After some moments, a window will show all the IP's available in coregen.
Click on + sign of Math Functions.
Then click on + sign of Floating Point.
Select the normal Floating-Point IP and click Next.
Click on + sign of Math Functions.
Then click on + sign of Floating Point.
Select the normal Floating-Point IP and click Next.
5) Upon this, a window will be opened where you can customize the selected IP. As you can see, the left side will show the IP symbol with input and output signals, and on right side, we have the parameters of IP which can be customized. Select the settings as shown below and then click Generate at the end.
So what kind of IP have we created here? Its a FP multiplier with 2 inputs and one output of single precision FP numbers. There is also a Clock input and RDY (Ready) output. A high on RDY signal shows that the current output is valid.
6) Coregen will generate all the files which are required for simulating or synthesizing the IP in your project. Upon completion, the CORE Generator creates and adds to the project, a file called component_name.xco. This is a file that records all the customization parameters used to create the core and the project options in effect when the core was generated. Double clicking on this file, will open the customization window, and you will be able to edit the IP later on if needed.
7) When the View mode is Implementation, select the .xco file, and then you can see various options under the Design tab down. Double click on the View HDL Instantiation Template. A file named component_name.vho will open, which shows the component declaration. This is useful, if we want to instantiate the IP later on.
8) Now we want to test this IP. For that purpose, I have written a testbench. Create a New Source in the same project, and copy and paste the following code in there. You can name the file as tb.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;ENTITY tb IS
END tb;
ARCHITECTURE behavior OF tb IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT ip_test
PORT(
a : IN std_logic_vector(31 downto 0);
b : IN std_logic_vector(31 downto 0);
clk : IN std_logic;
result : OUT std_logic_vector(31 downto 0);
rdy : OUT std_logic
);
END COMPONENT;
--Inputs
signal a : std_logic_vector(31 downto 0) := (others => '0');
signal b : std_logic_vector(31 downto 0) := (others => '0');
signal clk : std_logic := '0';
--Outputs
signal result : std_logic_vector(31 downto 0);
signal rdy : std_logic;
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: ip_test PORT MAP (
a => a,
b => b,
clk => clk,
result => result,
rdy => rdy
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
a <= x"4148F5C3"; --12.56
b <= x"42C80000"; --100.0
--result should be 1256 = x"449D0000"
wait;
end process;
END;
9) Double click on Simulate Behavioral Model. The ISIM window will open with the simulation waveform. The waveform should look like this:
Analysis:
The inputs applied were 12.56 and 100.0. These needed to be converted to FP representation before. I used an online tool for this. The result was also confirmed using the same tool.
Have you noticed the 6 clock cycle delay between the input and output? This is called latency of the design. If you remember, while creating the IP using coregen, we could have changed this value on Page 3. A lower latency will reduce the maximum clock frequency of the design and might also increase the usage of resources. Think carefully before changing the default value.
The tool used for this post is Xilinx ISE 14.6 and ISIM for simulation.
If i have to add data from Txt file like a= [32000*1] and b=[400*1] and multiply 1 row of a to 1 row of b then what i have to do.
ReplyDelete