1
0
mirror of https://github.com/antonblanchard/microwatt.git synced 2026-01-11 23:43:15 +00:00
antonblanchard.microwatt/cache_ram.vhdl
Paul Mackerras 6fe9dc9640 dcache: Reduce metavalue warnings
Among other changes, this makes the things that were previously
declared as signals of integer base type to be unsigned, since
unsigned can carry metavalues, and hence we can get the checking for
metavalues closer to the uses and therefore restrict the checking to
the situations where the signal really ought to be well defined.
We now have a couple more signals that indicate request validity to
help with that.

Non-fatal asserts have been sprinkled throughout to assist with
determining the cause of warnings from library functions (primarily
NUMERIC_STD.TO_INTEGER and NUMERIC_STD."=").

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
2022-08-12 20:17:20 +10:00

89 lines
2.7 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity cache_ram is
generic(
ROW_BITS : integer := 16;
WIDTH : integer := 64;
BYTEWID : integer := 8;
TRACE : boolean := false;
ADD_BUF : boolean := false
);
port(
clk : in std_logic;
rd_en : in std_logic;
rd_addr : in std_logic_vector(ROW_BITS - 1 downto 0);
rd_data : out std_logic_vector(WIDTH - 1 downto 0);
wr_sel : in std_logic_vector(WIDTH/BYTEWID - 1 downto 0);
wr_addr : in std_logic_vector(ROW_BITS - 1 downto 0);
wr_data : in std_logic_vector(WIDTH - 1 downto 0)
);
end cache_ram;
architecture rtl of cache_ram is
constant SIZE : integer := 2**ROW_BITS;
type ram_type is array (0 to SIZE - 1) of std_logic_vector(WIDTH - 1 downto 0);
signal ram : ram_type;
attribute ram_style : string;
attribute ram_style of ram : signal is "block";
signal rd_data0 : std_logic_vector(WIDTH - 1 downto 0);
begin
process(clk)
variable lbit : integer range 0 to WIDTH - 1;
variable mbit : integer range 0 to WIDTH - 1;
variable widx : integer range 0 to SIZE - 1;
constant sel0 : std_logic_vector(WIDTH/BYTEWID - 1 downto 0)
:= (others => '0');
begin
if rising_edge(clk) then
if TRACE then
if wr_sel /= sel0 then
report "write a:" & to_hstring(wr_addr) &
" sel:" & to_hstring(wr_sel) &
" dat:" & to_hstring(wr_data);
end if;
end if;
for i in 0 to WIDTH/BYTEWID-1 loop
lbit := i * BYTEWID;
mbit := lbit + BYTEWID - 1;
if wr_sel(i) = '1' then
assert not is_X(wr_addr);
widx := to_integer(unsigned(wr_addr));
ram(widx)(mbit downto lbit) <= wr_data(mbit downto lbit);
end if;
end loop;
if rd_en = '1' then
assert not is_X(rd_addr);
rd_data0 <= ram(to_integer(unsigned(rd_addr)));
if TRACE then
report "read a:" & to_hstring(rd_addr) &
" dat:" & to_hstring(ram(to_integer(unsigned(rd_addr))));
end if;
end if;
end if;
end process;
buf: if ADD_BUF generate
begin
process(clk)
begin
if rising_edge(clk) then
rd_data <= rd_data0;
end if;
end process;
end generate;
nobuf: if not ADD_BUF generate
begin
rd_data <= rd_data0;
end generate;
end;