VHDL register file synthesis

Discussion in 'VHDL' started by stoyan.shopov@gmail.com, Mar 15, 2005.

  1. Guest

    Hi everybody,
    I am quite new to VHDL and I have some questions. I am trying to
    build a register file consisting of 16 registers, each 32 bits wide.
    The register file I need must have two outputs - two of the registers
    must be driven on two output buses at any time. The register file
    is updated synchronously on the rising edge of clock.
    I use Xilinx ISE 6.2.
    I am sorry that I put here so much code, but it is simple code
    and should not take much time to read.

    As a building block I use the 'reg' entity listed below.

    entity reg is
    Port ( din : in std_logic_vector(31 downto 0); -- data input for
    register update
    dout : out std_logic_vector(31 downto 0); -- data output
    (tristate)
    dout1 : out std_logic_vector(31 downto 0); -- identical as
    dout above
    wr : in std_logic; -- write strobe
    wren : in std_logic; -- write enable; I shall make these clear
    below
    clk : in std_logic; -- clock input
    oe : in std_logic; -- output enable for dout output
    oe1 : in std_logic); -- output enable for daout1 output
    end reg;

    architecture Behavioral of reg is

    signal idata: std_logic_vector(31 downto 0);

    begin

    update_reg: process(clk)
    begin

    if clk'event and clk = '1' then
    if wr = '1' and wren = '1' then
    idata <= din;
    end if;
    end if;

    end process;

    drive_output: process(idata, oe, oe1)
    begin
    -- drive first output
    if oe = '1' then
    dout <= idata;
    else
    dout <= (others => 'Z');
    end if;
    -- drive second output
    if oe1 = '1' then
    dout1 <= idata;
    else
    dout1 <= (others => 'Z');
    end if;

    end process;

    end Behavioral;
    ----------------------------------------------------------------------------
    The register is updated on the rising edge of the clock, whenever at
    that
    time wr AND wren are both high.

    Using the reg entity, I have built a register file with the following
    structure:
    ----------------------------------------------------------------------------
    entity regarray is
    Port ( din : in std_logic_vector(31 downto 0); -- data input for
    register update
    dout : out std_logic_vector(31 downto 0); -- data output
    dout1 : out std_logic_vector(31 downto 0); -- second data
    output
    clk : in std_logic; -- clock input
    wr : in std_logic; -- write strobe
    wrsel : in std_logic_vector(3 downto 0); -- selects a
    register to update
    rsel : in std_logic_vector(3 downto 0); -- selects a
    register for dout
    rsel1 : in std_logic_vector(3 downto 0)); -- selects a
    register for dout1
    end regarray;

    architecture Behavioral of regarray is

    component reg is
    Port ( din : in std_logic_vector(31 downto 0);
    dout : out std_logic_vector(31 downto 0);
    dout1 : out std_logic_vector(31 downto 0);
    wr : in std_logic;
    wren : in std_logic;
    clk : in std_logic;
    oe : in std_logic;
    oe1 : in std_logic);
    end component;

    signal rseldec : std_logic_vector(15 downto 0); -- decoder for
    selecting a register for dout
    signal rseldec1 : std_logic_vector(15 downto 0); -- decoder for
    selecting a register for dout1
    signal wrseldec : std_logic_vector(15 downto 0); -- decoder for
    selecting a register to update

    begin

    -- instantiate registers - 16 registers
    reg0: reg port map(din, dout, dout1, wrseldec(0), wr, clk, rseldec(0),
    rseldec1(0));
    reg1: reg port map(din, dout, dout1, wrseldec(1), wr, clk, rseldec(1),
    rseldec1(1));
    ....
    reg15: reg port map(din, dout, dout1, wrseldec(15), wr, clk,
    rseldec(15), rseldec1(15));

    -- infer decoder for dout register select
    with rsel select rseldec <=
    "0000000000000001" when "0000",
    "0000000000000010" when "0001",
    ...
    "1000000000000000" when others;

    -- infer decoder for dout1 register select
    with rsel1 select rseldec1 <=
    "0000000000000001" when "0000",
    "0000000000000010" when "0001",
    ...
    "1000000000000000" when others;

    -- infer decoder for register update select
    with wrsel select wrseldec <=
    "0000000000000001" when "0000",
    "0000000000000010" when "0001",
    ...
    "1000000000000000" when others;

    end Behavioral;

    My question is: taking in account the requirements for the register
    file
    (two outputs, synchronous update), is my implementation correct?
    I had a look at the generated schematics (I use Xilinx ISE 6.2)
    and it looked fine to me - just what I had imagined - registers,
    decoders,
    tristate buffers. Is there a better way to code such a register file?
    I tried another implementation with two multiplexers instead of
    tri-state buses,
    but it was taking more space on the FPGA I use (Spartan 3).
    Also, I got some warning from the synthesizer that I am clueless about:
    WARNING:Xst:1904 - Unit regarray : signal N5634 : Multi-source of
    tristates is replaced by logic
    There are 64 such warnings and they are apparently concerning the two
    output
    buses. I think that I am not driving the tristate buffers properly,
    but this is the best I could think of. Can you help, please.
    Thank you very much!

    Stoyan Shopov
     
    , Mar 15, 2005
    #1
    1. Advertising

  2. HI,

    That is not the way to write Register Files. You could check the code
    below . It has synchronous write and asynchornous read.

    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;
    entity Regfile is
    generic( DATA_WIDTH : natural := 32;
    ADDRS_WIDTH : natural := 4
    );
    port(
    Data_In : in signed(DATA_WIDTH-1 downto 0); -- Input Data

    Addrs_In : in unsigned(ADDRS_WIDTH-1 downto 0); -- Input
    Address
    Addrs1_Out : in unsigned(ADDRS_WIDTH-1 downto 0); -- Output
    Address 1
    Addrs2_Out : in unsigned(ADDRS_WIDTH-1 downto 0); -- Output Address
    2
    Wr_En : in std_logic; -- Write Enable
    Clk : in std_logic; -- Global Clk

    Data1_Out : out signed(DATA_WIDTH-1 downto 0); -- Output Data 1
    Data2_Out : out signed(DATA_WIDTH-1 downto 0) -- Output Data 2
    );
    end entity Regfile;

    architecture Regfile_Arch of Regfile is
    -- Declarations of Register File type & signal
    type Regfile_type is array (natural range<>) of signed(DATA_WIDTH-1
    downto 0);
    signal Regfile_Coff : Regfile_type(0 to ADDRS_WIDTH-1);
    begin
    --------------------------------------------------------
    -- Concurrent Statements

    -- Regfile_Read Assignments
    Data1_Out <= Regfile_Coff(TO_INTEGER(Addrs1_Out));
    Data2_Out <= Regfile_Coff(TO_INTEGER(addrs2_Out));
    --------------------------------------------------------
    -- Sequential Process
    -- Register File Write Process
    Regfile_Write:process(Clk)
    begin

    if(RISING_EDGE(Clk))then
    if(Wr_En = '1')then
    Regfile_Coff(TO_INTEGER(Addrs_In)) <= Data_In;
    end if;
    end if;

    end process Regfile_Write;
    --------------------------------------------------------
    end architecture Regfile_Arch;
     
    Mohammed A khader, Mar 15, 2005
    #2
    1. Advertising

  3. wrote:

    > My question is: taking in account the requirements for the register
    > file
    > (two outputs, synchronous update), is my implementation correct?
    > I had a look at the generated schematics (I use Xilinx ISE 6.2)
    > and it looked fine to me - just what I had imagined - registers,
    > decoders, tristate buffers.


    That's a good sign, but the only way to
    answer the question is to write a simulation
    testbench and verify the waveforms.

    >Is there a better way to code such a register file?


    Consider deferring changes until verification
    is complete.

    -- Mike Treseler
     
    Mike Treseler, Mar 15, 2005
    #3
  4. Guest

    Thank you, Mohammed! I tried your code, not only it is more compact and
    readable but the synthesis tool managed to infer a dual port ram
    component, which is a primitive in the FPGA I use (Spartan 3) and so it
    took much less space than my implementation!
     
    , Mar 16, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. walala
    Replies:
    4
    Views:
    2,135
    Ralf Hildebrandt
    Sep 8, 2003
  2. walala
    Replies:
    4
    Views:
    1,231
    Technology Consultant
    Sep 9, 2003
  3. Mohammed  A khader

    Register Files for synthesis

    Mohammed A khader, Apr 30, 2005, in forum: VHDL
    Replies:
    1
    Views:
    630
    Mohammed A khader
    May 2, 2005
  4. afd
    Replies:
    1
    Views:
    8,419
    Colin Paul Gloster
    Mar 23, 2007
  5. Markus

    shift register synthesis

    Markus, Aug 16, 2007, in forum: VHDL
    Replies:
    1
    Views:
    567
Loading...

Share This Page