URL
https://opencores.org/ocsvn/xucpu/xucpu/trunk
Subversion Repositories xucpu
Compare Revisions
- This comparison shows the changes necessary to convert path
/xucpu
- from Rev 29 to Rev 30
- ↔ Reverse comparison
Rev 29 → Rev 30
/trunk/src/components/BRAM/cache.vhdl
0,0 → 1,99
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
|
ENTITY cache IS |
|
PORT ( |
clk : IN STD_LOGIC; |
address : IN STD_LOGIC_VECTOR(14 DOWNTO 0); |
instr : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)); |
|
END ENTITY cache; |
|
ARCHITECTURE Behavioral OF cache IS |
|
COMPONENT cache_block IS |
-- Cache memory block of 512x16 |
GENERIC ( |
w_data : NATURAL RANGE 1 TO 32 := 16; |
w_addr : NATURAL RANGE 8 TO 14 := 9); |
PORT ( |
clk : IN STD_LOGIC; |
we : IN STD_LOGIC; |
a1 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Data port address |
a2 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Instruction port address |
d1 : IN STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port input |
q1 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port output |
q2 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0)); -- Instruction port output |
|
END COMPONENT cache_block; |
|
SIGNAL column : STD_LOGIC_VECTOR(2 DOWNTO 0); |
SIGNAL row : STD_LOGIC_VECTOR(8 DOWNTO 0); |
SIGNAL tag : STD_LOGIC_VECTOR(2 DOWNTO 0); |
|
SIGNAL address_reg : STD_LOGIC_VECTOR(15 DOWNTO 0); |
SIGNAL instr_out : ARRAY(0 TO 7) OF STD_LOGIC_VECTOR(15 DOWNTO 0); |
|
BEGIN -- ARCHITECTURE Behavioral |
|
-- purpose: Register the input address at the same time it is |
-- registered in the block RAM |
-- type : sequential |
-- inputs : clk, rst, address |
-- outputs: address_reg |
AR1 : PROCESS (clk) IS |
BEGIN -- PROCESS AR1 |
IF rising_edge(clk) THEN |
address_reg <= address; |
END IF; |
END PROCESS AR1; |
|
-- Split the supplied address into three pieces |
column <= address_reg(2 DOWNTO 0); |
row <= address_reg(11 DOWNTO 3); |
tag <= address_reg(14 DOWNTO 12); |
|
-- Control data block with valid bits and tags |
CB1 : cache_block |
GENERIC MAP ( |
w_data => 4, |
w_addr => 9) |
PORT MAP ( |
clk => clk, |
we => we, |
a1 => row, |
a2 => (OTHERS => '0'), |
d1 => tag, |
q1 => cmp); |
|
-- Generate the cache memory in 8 columns |
C1 : FOR i IN 0 TO 7 GENERATE |
|
B0 : cache_block |
GENERIC MAP ( |
w_data => 16, |
w_addr => 9) |
PORT MAP ( |
clk => clk, |
we => we, |
a1 => row, |
a2 => (OTHERS => '0'), |
d1 => d1, |
q1 => instr_out(i)); |
|
END GENERATE C1; |
|
-- Select the instruction output based upon the column |
WITH column SELECT |
instr <= |
instr_out(0) WHEN "000", |
instr_out(1) WHEN "001", |
instr_out(2) WHEN "010", |
instr_out(3) WHEN "011", |
instr_out(4) WHEN "100", |
instr_out(5) WHEN "101", |
instr_out(6) WHEN "110", |
instr_out(7) WHEN "111"; |
|
END ARCHITECTURE Behavioral; |
/trunk/src/components/BRAM/cache_block.vhdl
0,0 → 1,54
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.numeric_std.ALL; |
|
ENTITY cache_block IS |
|
-- Cache memory block of 512x16 |
GENERIC ( |
w_data : NATURAL RANGE 1 TO 32 := 16; |
w_addr : NATURAL RANGE 8 TO 14 := 9); |
PORT ( |
clk : IN STD_LOGIC; |
we : IN STD_LOGIC; |
a1 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Data port address |
a2 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Instruction port address |
d1 : IN STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port input |
q1 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port output |
q2 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0)); -- Instruction port output |
|
END cache_block; |
|
ARCHITECTURE Behavioral OF cache_block IS |
|
SIGNAL address_reg_1 : STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); |
SIGNAL address_reg_2 : STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); |
|
BEGIN -- Behavioral |
|
-- purpose: Try to describe a proper block ram without needing to instantiate a BRAM |
-- type : sequential |
-- inputs : clk, we, a1, a2, d1 |
-- outputs: q1, q2 |
MP1 : PROCESS (clk, address_reg_1, address_reg_2, mem) |
BEGIN -- PROCESS MP1 |
|
-- Reading |
q1 <= STD_LOGIC_VECTOR(to_unsigned(mem(to_integer(UNSIGNED(address_reg_1))), w_data)); |
q2 <= STD_LOGIC_VECTOR(to_unsigned(mem(to_integer(UNSIGNED(address_reg_2))), w_data)); |
IF rising_edge(clk) THEN -- rising clock edge |
|
-- These work like the block RAM registers |
address_reg_1 <= a1; |
address_reg_2 <= a2; |
|
-- Writing |
IF we = '1' THEN |
mem(to_integer(UNSIGNED(a1))) <= to_integer(UNSIGNED(d1)); |
END IF; |
|
END IF; |
|
END PROCESS MP1; |
|
END Behavioral; |