123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.numeric_std.all;
- use work.mem_pkg.all;
- use work.core_pkg.all;
- use work.op_pkg.all;
- entity memu is
- port (
- -- to mem
- op : in memu_op_type;
- A : in data_type;
- W : in data_type;
- R : out data_type := (others => '0');
- B : out std_logic := '0';
- XL : out std_logic := '0';
- XS : out std_logic := '0';
- -- to memory controller
- D : in mem_in_type;
- M : out mem_out_type := MEM_OUT_NOP
- );
- end entity;
- architecture rtl of memu is
- type word_arr is array(0 to 3) of std_logic_vector(7 downto 0);
-
- -- write pipeline bytes
- alias W_0 : std_logic_vector(7 downto 0) is W(7 downto 0);
- alias W_1 : std_logic_vector(7 downto 0) is W(15 downto 8);
- alias W_2 : std_logic_vector(7 downto 0) is W(23 downto 16);
- alias W_3 : std_logic_vector(7 downto 0) is W(31 downto 24);
- signal W_arr : word_arr;
-
-
- -- read pipeline bytes
- alias R_0 : std_logic_vector(7 downto 0) is R(7 downto 0);
- alias R_1 : std_logic_vector(7 downto 0) is R(15 downto 8);
- alias R_2 : std_logic_vector(7 downto 0) is R(23 downto 16);
- alias R_3 : std_logic_vector(7 downto 0) is R(31 downto 24);
- signal R_arr : word_arr;
-
- -- write mem bytes
- alias MW_0 : std_logic_vector(7 downto 0) is M.wrdata(7 downto 0);
- alias MW_1 : std_logic_vector(7 downto 0) is M.wrdata(15 downto 8);
- alias MW_2 : std_logic_vector(7 downto 0) is M.wrdata(23 downto 16);
- alias MW_3 : std_logic_vector(7 downto 0) is M.wrdata(31 downto 24);
- signal MW_arr : word_arr;
-
- -- read mem bytes
- alias DR_0 : std_logic_vector(7 downto 0) is D.rddata(7 downto 0);
- alias DR_1 : std_logic_vector(7 downto 0) is D.rddata(15 downto 8);
- alias DR_2 : std_logic_vector(7 downto 0) is D.rddata(23 downto 16);
- alias DR_3 : std_logic_vector(7 downto 0) is D.rddata(31 downto 24);
- signal DR_arr : word_arr;
-
- -- adress alias
- alias A_byte : std_logic_vector(1 downto 0) is A(1 downto 0);
- -- signals
- -- signal exep_l, exep_s : std_logic;
- begin
-
- -- concurrent
- XL <= '1' when (op.memread = '1' and (
- ((op.memtype = MEM_H or op.memtype = MEM_HU) and A_byte(0) = '1') or -- cant access uneven half word
- ((op.memtype = MEM_W and A_byte /= "00") -- cant access word if not full
- )))
- else '0';
- XS <= '1' when (op.memwrite = '1' and (
- ((op.memtype = MEM_H or op.memtype = MEM_HU) and A_byte(0) = '1') or -- cant write uneven half word
- ((op.memtype = MEM_W and A_byte /= "00") -- cant write word if not full
- )))
- else '0';
-
- M.address <= A(15 downto 2);
-
- W_arr <= (W_0, W_1, W_2, W_3);
- R_0 <= R_arr(0);
- R_1 <= R_arr(1);
- R_2 <= R_arr(2);
- R_3 <= R_arr(3);
- MW_0 <= MW_arr(0);
- MW_1 <= MW_arr(1);
- MW_2 <= MW_arr(2);
- MW_3 <= MW_arr(3);
- DR_arr <= (DR_0, DR_1, DR_2, DR_3);
-
- M.address <= A(15 downto 2);
-
- -- memop
- M.rd <= op.memread when XL = '0' else '0';
- M.wr <= op.memwrite when XS = '0' else '0';
- B <= (op.memread and not XL) or D.busy;
-
- -- synchronous
- translation : process(all) -- very confuse but looks cool right :3
- begin
- case op.memtype is
- when MEM_B =>
- R_arr <= (0 => DR_arr(to_integer(unsigned(not A_byte))), others => (others => DR_arr(to_integer(unsigned(not A_byte)))(7)));
- MW_arr <= (others => (others => '-'));
- MW_arr(to_integer(unsigned(not A_byte))) <= W_arr(0);
- M.byteena <= (others => '0');
- M.byteena(to_integer(unsigned(not A_byte))) <= '1';
-
- when MEM_BU =>
- R_arr <= (0 => DR_arr(to_integer(unsigned(not A_byte))), others => (others => '0'));
- MW_arr <= (others => (others => '-'));
- MW_arr(to_integer(unsigned(not A_byte))) <= W_arr(0);
- M.byteena <= (others => '0');
- M.byteena(to_integer(unsigned(not A_byte))) <= '1';
-
- when MEM_H =>
- if A_byte(1) = '0' then
- R_arr <= (0 => DR_arr(3), 1 => DR_arr(2), others => (others => DR_arr(2)(7)));
- MW_arr <= (3 => W_arr(0), 2 => W_arr(1), others => (others => '-'));
- M.byteena <= "1100";
- else
- R_arr <= (0 => DR_arr(1), 1 => DR_arr(0), others => (others => DR_arr(0)(7)));
- MW_arr <= (1 => W_arr(0), 0 => W_arr(1), others => (others => '-'));
- M.byteena <= "0011";
- end if;
-
- when MEM_HU =>
- if A_byte(1) = '0' then
- R_arr <= (0 => DR_arr(3), 1 => DR_arr(2), others => (others => '0'));
- MW_arr <= (3 => W_arr(0), 2 => W_arr(1), others => (others => '-'));
- M.byteena <= "1100";
- else
- R_arr <= (0 => DR_arr(1), 1 => DR_arr(0), others => (others => '0'));
- MW_arr <= (1 => W_arr(0), 0 => W_arr(1), others => (others => '-'));
- M.byteena <= "0011";
- end if;
-
- when MEM_W =>
- R_arr <= (0 => DR_arr(3), 1 => DR_arr(2), 2 => DR_arr(1), 3 => DR_arr(0));
- MW_arr <= (0 => W_arr(3), 1 => W_arr(2), 2 => W_arr(1), 3 => W_arr(0));
- M.byteena <= "1111";
- end case;
-
- end process;
-
- end architecture;
|