OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [riverlib/] [cache/] [dcache.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
-----------------------------------------------------------------------------
2
--! @file
3
--! @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
--! @author    Sergey Khabarov - sergeykhbr@gmail.com
5
--! @brief     Data Cache.
6
------------------------------------------------------------------------------
7
 
8
library ieee;
9
use ieee.std_logic_1164.all;
10
library commonlib;
11
use commonlib.types_common.all;
12
--! RIVER CPU specific library.
13
library riverlib;
14
--! RIVER CPU configuration constants.
15
use riverlib.river_cfg.all;
16
 
17
 
18
entity DCache is
19
  port (
20
    i_clk : in std_logic;                              -- CPU clock
21
    i_nrst : in std_logic;                             -- Reset. Active LOW.
22
    -- Data path:
23
    i_req_data_valid : in std_logic;
24
    i_req_data_write : in std_logic;
25
    i_req_data_sz : in std_logic_vector(1 downto 0);
26
    i_req_data_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
27
    i_req_data_data : in std_logic_vector(RISCV_ARCH-1 downto 0);
28
    o_req_data_ready : out std_logic;
29
    o_resp_data_valid : out std_logic;
30
    o_resp_data_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
31
    o_resp_data_data : out std_logic_vector(RISCV_ARCH-1 downto 0);
32
    i_resp_data_ready : in std_logic;
33
    -- Memory interface:
34
    i_req_mem_ready : in std_logic;
35
    o_req_mem_valid : out std_logic;
36
    o_req_mem_write : out std_logic;
37
    o_req_mem_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
38
    o_req_mem_strob : out std_logic_vector(BUS_DATA_BYTES-1 downto 0);
39
    o_req_mem_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0);
40
    i_resp_mem_data_valid : in std_logic;
41
    i_resp_mem_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0);
42
    -- Debug Signals:
43
    o_dstate : out std_logic_vector(1 downto 0)
44
  );
45
end;
46
 
47
architecture arch_DCache of DCache is
48
 
49
  constant State_Idle : std_logic_vector(1 downto 0) := "00";
50
  constant State_WaitGrant : std_logic_vector(1 downto 0) := "01";
51
  constant State_WaitResp : std_logic_vector(1 downto 0) := "10";
52
  constant State_WaitAccept : std_logic_vector(1 downto 0) := "11";
53
 
54
  type RegistersType is record
55
      dline_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0);
56
      dline_addr_req : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
57
      dline_size_req : std_logic_vector(1 downto 0);
58
      state : std_logic_vector(1 downto 0);
59
  end record;
60
 
61
  signal r, rin : RegistersType;
62
 
63
begin
64
 
65
  comb : process(i_nrst, i_req_data_valid, i_req_data_write, i_req_data_sz,
66
                i_req_data_addr, i_req_data_data, i_resp_mem_data_valid,
67
                i_resp_mem_data, i_req_mem_ready, i_resp_data_ready, r)
68
    variable v : RegistersType;
69
    variable w_wait_response : std_logic;
70
    variable w_o_req_data_ready : std_logic;
71
    variable w_o_req_mem_valid : std_logic;
72
    variable wb_o_req_mem_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
73
    variable wb_o_req_strob : std_logic_vector(BUS_DATA_BYTES-1 downto 0);
74
    variable wb_o_req_wdata : std_logic_vector(BUS_DATA_WIDTH-1 downto 0);
75
    variable w_req_fire : std_logic;
76
    variable w_o_resp_valid : std_logic;
77
    variable wb_o_resp_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
78
    variable wb_resp_data_mux : std_logic_vector(BUS_DATA_WIDTH-1 downto 0);
79
    variable wb_o_resp_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0);
80
    variable wb_rtmp : std_logic_vector(BUS_DATA_WIDTH-1 downto 0);
81
  begin
82
 
83
    v := r;
84
    wb_o_req_strob := (others => '0');
85
    wb_o_req_wdata := (others => '0');
86
    wb_o_resp_data := (others => '0');
87
    wb_rtmp := (others => '0');
88
 
89
    w_wait_response := '0';
90
    if r.state = State_WaitResp and i_resp_mem_data_valid = '0' then
91
        w_wait_response := '1';
92
    end if;
93
 
94
    case i_req_data_sz is
95
    when "00" =>
96
        wb_o_req_wdata := i_req_data_data(7 downto 0) &
97
            i_req_data_data(7 downto 0) & i_req_data_data(7 downto 0) &
98
            i_req_data_data(7 downto 0) & i_req_data_data(7 downto 0) &
99
            i_req_data_data(7 downto 0) & i_req_data_data(7 downto 0) &
100
            i_req_data_data(7 downto 0);
101
        if i_req_data_addr(2 downto 0) = "000" then
102
            wb_o_req_strob := X"01";
103
        elsif i_req_data_addr(2 downto 0) = "001" then
104
            wb_o_req_strob := X"02";
105
        elsif i_req_data_addr(2 downto 0) = "010" then
106
            wb_o_req_strob := X"04";
107
        elsif i_req_data_addr(2 downto 0) = "011" then
108
            wb_o_req_strob := X"08";
109
        elsif i_req_data_addr(2 downto 0) = "100" then
110
            wb_o_req_strob := X"10";
111
        elsif i_req_data_addr(2 downto 0) = "101" then
112
            wb_o_req_strob := X"20";
113
        elsif i_req_data_addr(2 downto 0) = "110" then
114
            wb_o_req_strob := X"40";
115
        elsif i_req_data_addr(2 downto 0) = "111" then
116
            wb_o_req_strob := X"80";
117
        end if;
118
    when "01" =>
119
        wb_o_req_wdata := i_req_data_data(15 downto 0) &
120
            i_req_data_data(15 downto 0) & i_req_data_data(15 downto 0) &
121
            i_req_data_data(15 downto 0);
122
        if i_req_data_addr(2 downto 1) = "00" then
123
            wb_o_req_strob := X"03";
124
        elsif i_req_data_addr(2 downto 1) = "01" then
125
            wb_o_req_strob := X"0C";
126
        elsif i_req_data_addr(2 downto 1) = "10" then
127
            wb_o_req_strob := X"30";
128
        else
129
            wb_o_req_strob := X"C0";
130
        end if;
131
    when "10" =>
132
        wb_o_req_wdata := i_req_data_data(31 downto 0) &
133
                          i_req_data_data(31 downto 0);
134
        if i_req_data_addr(2) = '1' then
135
            wb_o_req_strob := X"F0";
136
        else
137
            wb_o_req_strob := X"0F";
138
        end if;
139
    when "11" =>
140
        wb_o_req_wdata := i_req_data_data;
141
        wb_o_req_strob := X"FF";
142
    when others =>
143
    end case;
144
 
145
 
146
    w_o_req_mem_valid := i_req_data_valid and not w_wait_response;
147
    wb_o_req_mem_addr := i_req_data_addr(BUS_ADDR_WIDTH-1 downto 3) & "000";
148
    w_o_req_data_ready := i_req_mem_ready;
149
    w_req_fire := w_o_req_mem_valid and w_o_req_data_ready;
150
    case r.state is
151
    when State_Idle =>
152
        if i_req_data_valid = '1' then
153
            if i_req_mem_ready = '1' then
154
                v.state := State_WaitResp;
155
            else
156
                v.state := State_WaitGrant;
157
            end if;
158
        end if;
159
    when State_WaitGrant =>
160
        if i_req_mem_ready = '1' then
161
            v.state := State_WaitResp;
162
        end if;
163
    when State_WaitResp =>
164
        if i_resp_mem_data_valid = '1' then
165
            if i_resp_data_ready = '0' then
166
                v.state := State_WaitAccept;
167
            elsif i_req_data_valid = '0' then
168
                v.state := State_Idle;
169
            else
170
                -- New request
171
                if i_req_mem_ready = '1' then
172
                    v.state := State_WaitResp;
173
                else
174
                    v.state := State_WaitGrant;
175
                end if;
176
            end if;
177
        end if;
178
    when State_WaitAccept =>
179
        if i_resp_data_ready = '1' then
180
            if i_req_data_valid = '0' then
181
                v.state := State_Idle;
182
            else
183
                if i_req_mem_ready = '1' then
184
                    v.state := State_WaitResp;
185
                else
186
                    v.state := State_WaitGrant;
187
                end if;
188
            end if;
189
        end if;
190
    when others =>
191
    end case;
192
 
193
    if w_req_fire = '1' then
194
        v.dline_addr_req := i_req_data_addr;
195
        v.dline_size_req := i_req_data_sz;
196
    end if;
197
    if i_resp_mem_data_valid = '1' then
198
        v.dline_data := i_resp_mem_data;
199
    end if;
200
 
201
    wb_o_resp_addr := r.dline_addr_req;
202
    if r.state = State_WaitAccept then
203
        w_o_resp_valid := '1';
204
        wb_resp_data_mux := r.dline_data;
205
    else
206
        w_o_resp_valid := i_resp_mem_data_valid;
207
        wb_resp_data_mux := i_resp_mem_data;
208
    end if;
209
 
210
    case r.dline_addr_req(2 downto 0) is
211
    when "001" =>
212
        wb_rtmp := X"00" & wb_resp_data_mux(63 downto 8);
213
    when "010" =>
214
        wb_rtmp := X"0000" & wb_resp_data_mux(63 downto 16);
215
    when "011" =>
216
        wb_rtmp := X"000000" & wb_resp_data_mux(63 downto 24);
217
    when "100" =>
218
        wb_rtmp := X"00000000" & wb_resp_data_mux(63 downto 32);
219
    when "101" =>
220
        wb_rtmp := X"0000000000" & wb_resp_data_mux(63 downto 40);
221
    when "110" =>
222
        wb_rtmp := X"000000000000" & wb_resp_data_mux(63 downto 48);
223
    when "111" =>
224
        wb_rtmp := X"00000000000000" & wb_resp_data_mux(63 downto 56);
225
    when others =>
226
        wb_rtmp := wb_resp_data_mux;
227
    end case;
228
 
229
    case r.dline_size_req is
230
    when "00" =>
231
        wb_o_resp_data(7 downto 0) := wb_rtmp(7 downto 0);
232
    when "01" =>
233
        wb_o_resp_data(15 downto 0) := wb_rtmp(15 downto 0);
234
    when "10" =>
235
        wb_o_resp_data(31 downto 0) := wb_rtmp(31 downto 0);
236
    when others =>
237
        wb_o_resp_data := wb_rtmp;
238
    end case;
239
 
240
    if i_nrst = '0' then
241
        v.dline_addr_req := (others => '0');
242
        v.dline_size_req := (others => '0');
243
        v.dline_data := (others => '0');
244
        v.state := State_Idle;
245
    end if;
246
 
247
    o_req_data_ready <= w_o_req_data_ready;
248
 
249
    o_req_mem_valid <= w_o_req_mem_valid;
250
    o_req_mem_addr <= wb_o_req_mem_addr;
251
    o_req_mem_write <= i_req_data_write;
252
    o_req_mem_strob <= wb_o_req_strob;
253
    o_req_mem_data <= wb_o_req_wdata;
254
 
255
    o_resp_data_valid <= w_o_resp_valid;
256
    o_resp_data_data <= wb_o_resp_data;
257
    o_resp_data_addr <= wb_o_resp_addr;
258
    o_dstate <= r.state;
259
 
260
    rin <= v;
261
  end process;
262
 
263
  -- registers:
264
  regs : process(i_clk)
265
  begin
266
     if rising_edge(i_clk) then
267
        r <= rin;
268
     end if;
269
  end process;
270
 
271
end;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.