VHDL coding tips and tricks: Using Xilinx primitives in your design-An example

Thursday, August 12, 2010

Using Xilinx primitives in your design-An example

    Xilinx has provided a library named "UNISIM" which contains the component declarations for all Xilinx primitives and points to the models that will be used for simulation.This library is used during functional simulation and contains descriptions for all the device primitives, or lowest-level building blocks.
    In this post I will show you how to use a primitive in your design.In the example I am using the primitive named "RAMB16_S2" which is 8k x 2 Single-Port RAM for Spartan-3E FPGA. This primitive is instantiated twice to make 8k x 4 single port RAM.
    The code is given below.Note that I have made the code in the form of a testbench.So the below code is not synthesisable.This code is just for guiding you, how to use Xilinx primitives in your design.The code is well commented. So I hope I need not explain about the working of the code.Here in order to create a 8k x 4 RAM I used two 8k x 2 RAM's side by side.One RAM used to store the LSB 2 bits of the data while the 2nd RAM is used to store the MSB 2 bits of the data.Note that the address is same for both the RAM's.
    See the way I have instantiated the primitive in the design.Also don't forget to add the UNISIM library to the design.


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
--Remember to add this library when you use xilinx primitives from Language templates.
library unisim;
use unisim.vcomponents.all;

entity ram_test is
end ram_test;

architecture Behavioral of ram_test is

--signal declarations.
signal clk,en,ssr,we : std_logic:='0';
signal Dout,Din : std_logic_vector(3 downto 0):="0000";
signal addr : std_logic_vector(12 downto 0):=(others => '0');

begin

--RAMB16_S2 is 8k x 2 Single-Port RAM for Spartan-3E.We use this to create 8k x 4 Single-Port RAM.
--Initialize RAM which carries LSB 2 bits of the data.
RAM1  : RAMB16_S2 port map (
      DO => Dout(1 downto 0),      -- 2-bit Data Output
      ADDR => ADDR,  -- 13-bit Address Input
      CLK => CLK,    -- Clock
      DI => Din(1 downto 0),      -- 2-bit Data Input
      EN => EN,      -- RAM Enable Input
      SSR => SSR,    -- Synchronous Set/Reset Input
      WE => WE       -- Write Enable Input
   )

--Initialize RAM which carries MSB 2 bits of the data.
RAM2  : RAMB16_S2 port map (
      DO => Dout(3 downto 2),      -- 2-bit Data Output
      ADDR => ADDR,  -- 13-bit Address Input
      CLK => CLK,    -- Clock
      DI => Din(3 downto 2),      -- 2-bit Data Input
      EN => EN,      -- RAM Enable Input
      SSR => SSR,    -- Synchronous Set/Reset Input
      WE => WE       -- Write Enable Input
   );

--100 MHz clock generation for testing process.
clk_process : process
begin
wait for 5 ns;
clk <= not clk;
end process;

--Writing and Reading RAM.RAM has a depth of 13 bits and has a width of 4 bits.
simulate : process
begin
        en <='1';
        we <= '1';
        --Write the value "i" at the address "i" for 10 clock cycles.
        for i in 0 to 10 loop
                addr <= conv_std_logic_vector(i,13);
                din <= conv_std_logic_vector(i,4);
                wait for 10 ns;
        end loop;
        we<= '0';
        --Read the RAM for addresses from 0 to 20.
        for i in 0 to 20 loop
                addr <= conv_std_logic_vector(i,13);
                wait for 10 ns;
        end loop;

end process;

end Behavioral;


No comments:

Post a Comment