0

I am trying to implement a cache memory 16 * 37 in VHDL in DesignWorks 5. The code is given below. The code runs but when i change values from IO panel or even simulate anyway, the timing diagram shows nothing and basically the code is not running for some reason. Any suggestions would be really helpful.

Code:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity Cache is
port(cs, r, clr : in std_logic;
    data : in std_logic_vector(31 downto 0);
    addr : in std_logic_vector(7 downto 0);
    cline : out std_logic_vector(31 downto 0);
    ctag: out std_logic_vector(3 downto 0);
    v : out std_logic);
end Cache;

architecture behav of Cache is
type RAM is array (0 to 15) of std_logic_vector(36 downto 0); 
begin 
 process is
 variable M : RAM; 
 variable locn : natural; 
 variable temp_val : std_logic_vector(36 downto 0); 
 variable cline_val : std_logic_vector(31 downto 0);
 variable ctag_val : std_logic_vector(3 downto 0);
 variable v_val : std_logic;
    begin

        if cs = '1' then
            locn := to_integer(addr); 
            if r = '1' then 
                temp_val := M(locn); 
                cline_val := temp_val(31 downto 0);
                ctag_val := temp_val(35 downto 32);
                v_val := temp_val(36);
            else
                temp_val(31 downto 0) := data;
                temp_val(35 downto 32) := addr(3 downto 0);
                temp_val(36) := '1';
                M(locn) := temp_val;
                v_val := 'Z'; 
                ctag_val:= "ZZZZ"; 
                cline_val:= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
            end if; 
        end if; 
        if clr ='1' then
            locn := 0;
            while(locn<16) loop
                M(locn) := X"000000000" + "0";
                locn:=locn+1;
            end loop;
        end if;
    cline <= cline_val; 
    ctag <= ctag_val;
    v <= v_val;
    wait on cs; 
end process;

end behav;
NoorUllah
  • 621
  • 1
  • 5
  • 7
  • This code will not be syntesizable... I also would prefer some kind of comment lines or explantions especially for single character identifiers, so other readers on SF can understand your code. – Paebbels Dec 01 '14 at 07:48

1 Answers1

0

This line:

M(locn) := X"000000000" + "0"; 

appears incorrect.

M is your ram array type with an element length of 37. A 36 bit zero added to zero is still 36 bits (it doesn't look like you reached this statement, it would be a run time error).

To make a length 37 vector of '0' values use `(others => '0').

You can also use a for loop for the ram clear, you need to not use an index of 16, it's out of range, which tells us you didn't reach the clear either.

I think you ought to show us your stimulus otherwise your problems can't be reproduced.

Your missing data and addr as sensitivity elements (and ya, you case cs surrounds, but you want to build a hardware model here).

Switch to a sensitivity list (cs, data, addr).

locn is an unconstrained natural and should have a range matching the array type ram (0 to 15). Notice your while loop reaches 16. Really, use a for loop (shown below). The reason for constraining locn is to prevent a bound error when accessing ram(locn).

Note for converting addr to a natural (locn) you need to AND mask addr with a length four run of '1's to prevent a range error for normal ram operations.

The package numeric_std is an affectation, it's easier than passing a couple of command line options to ghdl (ieee=synopsys -fexplict) during analysis and elaboration.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity cache is
    port (
        cs, r, clr: in  std_logic;
        data:       in  std_logic_vector(31 downto 0);
        addr:       in  std_logic_vector(7 downto 0);
        cline:      out std_logic_vector(31 downto 0);
        ctag:       out std_logic_vector(3 downto 0);
        v:          out std_logic
    );
end entity;

architecture behav of cache is
    type ram is array (0 to 15) of std_logic_vector(36 downto 0);    
begin 

    process (cs, data, addr)
        variable m : ram; 
        variable locn : natural range (ram'range); 
        variable temp_val : std_logic_vector(36 downto 0); 
        variable cline_val : std_logic_vector(31 downto 0);
        variable ctag_val : std_logic_vector(3 downto 0);
        variable v_val : std_logic;
    begin
        if cs = '1' then
            locn := to_integer(unsigned(addr and x"0F")); 
            if r = '1' then 
                temp_val := m(locn); 
                cline_val := temp_val(31 downto 0);
                ctag_val := temp_val(35 downto 32);
                v_val := temp_val(36);
            else
                temp_val(31 downto 0) := data;
                temp_val(35 downto 32) := addr(3 downto 0);
                temp_val(36) := '1';
                m(locn) := temp_val;
                v_val := 'Z'; 
                ctag_val:= "ZZZZ"; 
                cline_val:= (others => 'Z');
            end if; 
        end if; 
        if clr ='1' then
            for i in ram'range loop
                m(i) := (others => '0');
            end loop;
        end if;
        cline <= cline_val; 
        ctag <= ctag_val;
        v <= v_val;
    end process;
end architecture;

This code analyzes and elaborates, you could have an error somewhere I didn't mention, and bound (range) errors show up at run time in assignments (expressions can not care).

And one final bit:

            temp_val(31 downto 0) := data;
            temp_val(35 downto 32) := addr(3 downto 0);
            temp_val(36) := '1';

can be expressed:

            temp_val:= '1' & addr(3 downto 0) & data;

As well as:

            locn := to_integer(addr);

expressed as:

            locn := to_integer(addr(3 downto 0));

You can also create an AND mask with a length defined algorithmically from the ram'range should you set the ram size with a generic.

And without seeing your stimulus there are several places that could cause run time errors. Check your console output.