Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

VHDL writing in memory

Hi,

I have a hardware design running on a Cyclone IV FPGA and a software part running on a Nios II cpu on the very same FPGA. Both are sharing a dual port FPGA memory. I want the hardware part to write data on the memory and the software part to read it. The reading seems to be OK but the writing is not. Here is the VHDL code I use:

library ieee;use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
entity ctrl is
    port(
        data : out std_logic_vector(7 downto 0);
        wen : out std_logic := '0';
        addr : out std_logic_vector(14 downto 0):=(others=>'0');
        clk : in std_logic);
end ctrl;
architecture rtl of ctrl is
    signal step : integer := 1;
begin
    process(clk)
    begin
        if clk'event and clk='1' then
            data <= "00000001";
            if step<4 then
                step <= step+1;
            end if;
            addr <= std_logic_vector(to_unsigned(step, addr'length));
            wen <= '1';
        end if;
    end process;
end rtl;

What I'd expect is the values written at addresses 2, 3 and 4 to be 1 but I only read 1 at address 4, others are 0.

I'm sure I'm messing something up in the sequential and concurrent statements but I can't solve this.

Could someone help me?

Thanks.

17 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The difference is because a signal in VHDL takes the last value assigned to it. In your origional code, it is reset inside the the "if hold = 10 then" branch, but this is overridden with hold <= hold + 1, hence it is never reset to 0.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    That works but I don't understand what is really different. Can you explain?

    --- Quote End ---

    There are two ways to set logic priority:

    explicit and default

    explicit

    
    if count = 10 then
        count <= 0;
    else
       count <= count + 1;
    end if;
    

    default (conditional)

    
    count <= count + 1;
    if count = 10 then
        count <= 0;
    end if;
    

    In vhdl process the last statement overwrites so if this last statement is conditional that is ok.

    if it is not conditional like your code then it implies unconditional update and compiler optimises off the previous assignment

    --- Quote Start ---

    Also I have to make the hold time to be at least 8 clock cycles. Is there a document telling that?

    --- Quote End ---

    What is this hold time?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    What is this hold time?

    --- Quote End ---

    It's the "hold" variable in the conditional test.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    It's the "hold" variable in the conditional test.

    --- Quote End ---

    I don't get it. hold is your local variable and you ask for a document on it?

    You are already delaying hold for 10 clock cycles before incrementing step.

    if you want further factor of 8 then just make it 80 instead of 10 so you increment every 80 clocks.

    You also need to constrain the range of your integers
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    OK for the range.

    My hold local variable is there for the signals to keep a value for several clock cycles. Maybe it's not the good way of doing that. Tell me how to do that, I'm not used to it...
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    OK for the range.

    My hold local variable is there for the signals to keep a value for several clock cycles. Maybe it's not the good way of doing that. Tell me how to do that, I'm not used to it...

    --- Quote End ---

    you already done that. Here is my version

    
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    entity ctrl is
        port(
            data        : out std_logic_vector(7 downto 0);
            wen        : out std_logic := '0';
            addr        : out std_logic_vector(14 downto 0):=(others=>'0');
            clk        : in std_logic);
    end ctrl;
    architecture rtl of ctrl is
        signal count1 : integer range 0 to 15 := 0;
        signal count2 : integer range 0 to 7 := 0;
         
    begin
        
        process(clk)
        begin
            if clk'event and clk='1' then
              wen <= '0';
              if count1 /= 15 then
                  count1 <= count1 + 1;
              else
                  count1 <= 0;
                  if count2 /= 7 then
                     count2 <= count2 + 1;
                  else
                     count2 <= 0;
                     wen <= '1';
                  end if;
               end if;
            end if;
        end process;
        
        data <= std_logic_vector(to_unsigned(count1, data'length));
        addr <= std_logic_vector(to_unsigned(count2, addr'length));
          
    end rtl;
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You generate a "wen" (write enable) which is active for one period of clk (20ns ?)

    Is it enough for your RAM ?

    With your last code, you are only writing at address addr = 0 !