]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/blob - hw/mem.vhd
Initial commit for MBLite+ Tumbl (used as coprocessor)
[fpga/lx-cpu1/tumbl.git] / hw / mem.vhd
1 ---------------------------------------------------------------------------------
2 --
3 --  Entity:       mem
4 --  Filename:     mem.vhd
5 --  Description:  the Memory (MEM) control unit for
6 --                the TUD MB-Lite implementation
7 --
8 --  Author:       Huib Lincklaen Arriens
9 --                Delft University of Technology
10 --                Faculty EEMCS, Department ME&CE, Circuits and Systems
11 --  Date:         October, 2010
12 --
13 --  Modified:     December, 2010: handle S_FSL Data Input (Huib)
14 --  Remarks:
15 --------------------------------------------------------------------------------
16
17
18 LIBRARY IEEE;
19 USE IEEE.std_logic_1164.all;
20 USE work.mbl_Pkg.all;
21
22
23 --------------------------------------------------------------------------------
24 ENTITY mem IS
25 --------------------------------------------------------------------------------
26     PORT (
27         EX2MEM_i    :  IN EX2MEM_Type;
28         --
29         DMEMB_i     :  IN DMEMB2CORE_Type;
30         DMEMB_o     : OUT CORE2DMEMB_Type;
31         --
32         FSL_S2MEM_i :  IN FSL_S2MEM_Type;
33         --
34         MEM_REG_i   :  IN MEM_REG_Type;
35         MEM_REG_o   : OUT MEM_REG_Type;
36         --
37         MEM_WRB_o   : OUT WRB_Type;
38         MEM2CTRL_o  : OUT MEM2CTRL_Type
39         );
40 END ENTITY mem;
41
42
43 --------------------------------------------------------------------------------
44 ARCHITECTURE rtl OF mem IS
45 --------------------------------------------------------------------------------
46
47 BEGIN
48
49     -- writeback in case of reads from the data memory bus:
50     -- delay wrb-ctrl signals (see core_ctrl) to stay in sync
51     -- with synchronous dmem data output
52     -- Following are only the unconditional pass-through signals. More are in the p_mem process.
53     MEM_REG_o.wrb_Action  <= EX2MEM_i.wrb_Action;
54     MEM_REG_o.exeq_result <= EX2MEM_i.exeq_result;
55     MEM_REG_o.byte_Enable <= EX2MEM_i.byte_Enable;
56     MEM_REG_o.wrix_rD     <= EX2MEM_i.wrix_rD;
57     --
58     MEM_WRB_o.wrb_Action <= MEM_REG_i.wrb_Action;
59     MEM_WRB_o.wrix_rD    <= MEM_REG_i.wrix_rD;
60     -- also signal 'slow memory decices' and interrupts from devices
61     MEM2CTRL_o.clken <= DMEMB_i.clken;
62     MEM2CTRL_o.int   <= DMEMB_i.int;
63     -- pass byte_select signal (NOTE: BIG ENDIAN)
64     DMEMB_o.bSel     <= EX2MEM_i.byte_Enable;
65
66 p_mem:
67     PROCESS (EX2MEM_i, DMEMB_i, MEM_REG_i, FSL_S2MEM_i)
68         VARIABLE exeq_data_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
69         VARIABLE dmem_data_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
70
71     BEGIN
72
73         -- always align Big Endian input data from memory(-bus)
74         CASE MEM_REG_i.byte_Enable IS
75             WHEN "1000" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(31 DOWNTO 24);
76             WHEN "0100" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(23 DOWNTO 16);
77             WHEN "0010" => dmem_data_v := C_24_ZEROS & DMEMB_i.data(15 DOWNTO  8);
78             WHEN "0001" => dmem_data_v := C_24_ZEROS & DMEMB_i.data( 7 DOWNTO  0);
79             WHEN "1100" => dmem_data_v := C_16_ZEROS & DMEMB_i.data(31 DOWNTO 16);
80             WHEN "0011" => dmem_data_v := C_16_ZEROS & DMEMB_i.data(15 DOWNTO  0);
81             WHEN OTHERS => dmem_data_v :=              DMEMB_i.data;
82         END CASE;
83
84         -- output to dmem-bus
85 --      DMEMB_o.addr <= EX2MEM_i.exeq_result;
86         CASE EX2MEM_i.mem_Action IS
87             WHEN WR_MEM =>
88                 -- write (or forward) to data memory bus
89                 DMEMB_o.addr <= EX2MEM_i.exeq_result;
90                 DMEMB_o.ena  <= '1';
91                 DMEMB_o.wre  <= '1';
92                 -- Note: use MEM_REG_i here, since MEM_WRB_o (output) cannot be read
93                 IF ((MEM_REG_i.wrb_Action /= NO_WRB) AND
94                         (EX2MEM_i.wrix_rD = MEM_REG_i.wrix_rD)) THEN
95                     CASE MEM_REG_i.wrb_Action IS
96                         WHEN WRB_EX  =>
97                             -- forward exeq output, to handle e.g. add rD,rA,xx; sw rD,mem[y]; ...
98                             exeq_data_v := MEM_REG_i.exeq_result;
99                         WHEN WRB_FSL =>
100                             -- forward FSL_S input, to handle e.g. nget rD,rFSLx; swi rD,mem[x],xx; ...
101                             exeq_data_v := FSL_S2MEM_i.S_Data;
102                         WHEN OTHERS  =>
103                             -- forward mem_data just read, to handle e.g. lhu rD,mem[x]; sh rD,mem[y]; ...
104                             exeq_data_v := dmem_data_v;
105                     END CASE;
106                 ELSE
107                     exeq_data_v := EX2MEM_i.data_rD;
108                 END IF;
109                 -- output data will be in Big Endian format
110                 CASE EX2MEM_i.byte_Enable IS
111                     WHEN "1000" => DMEMB_o.data <=              exeq_data_v( 7 DOWNTO 0) & C_24_ZEROS;
112                     WHEN "0100" => DMEMB_o.data <=  C_8_ZEROS & exeq_data_v( 7 DOWNTO 0) & C_16_ZEROS;
113                     WHEN "0010" => DMEMB_o.data <= C_16_ZEROS & exeq_data_v( 7 DOWNTO 0) &  C_8_ZEROS;
114                     WHEN "0001" => DMEMB_o.data <= C_24_ZEROS & exeq_data_v( 7 DOWNTO 0);
115                     WHEN "1100" => DMEMB_o.data <=              exeq_data_v(15 DOWNTO 0) & C_16_ZEROS;
116                     WHEN "0011" => DMEMB_o.data <= C_16_ZEROS & exeq_data_v(15 DOWNTO 0);
117                     WHEN OTHERS => DMEMB_o.data <=              exeq_data_v;
118                 END CASE;
119             WHEN RD_MEM =>
120                 -- read from data memory bus
121                 DMEMB_o.addr <= EX2MEM_i.exeq_result;
122                 DMEMB_o.ena  <= '1';
123                 DMEMB_o.wre  <= '0';
124                 DMEMB_o.data <= EX2MEM_i.data_rD;   -- (OTHERS => 'Z');
125             WHEN OTHERS =>      -- NO_MEM
126                 DMEMB_o.addr <= C_32_ZEROS;
127                 DMEMB_o.ena  <= '0';
128                 DMEMB_o.wre  <= '0';
129                 DMEMB_o.data <= EX2MEM_i.data_rD;   -- (OTHERS => 'Z');
130         END CASE;
131
132         -- additional wrb signals
133         CASE MEM_REG_i.wrb_Action IS
134             WHEN WRB_MEM => MEM_WRB_o.data_rD <= dmem_data_v;
135             WHEN WRB_FSL => MEM_WRB_o.data_rD <= FSL_S2MEM_i.S_Data;
136             WHEN OTHERS  => MEM_WRB_o.data_rD <= MEM_REG_i.exeq_result;
137         END CASE;
138
139     END PROCESS;
140
141 END ARCHITECTURE rtl;