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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [riverlib/] [core/] [memaccess.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     CPU Memory Access stage.
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 MemAccess is
19
  port (
20
    i_clk  : in std_logic;
21
    i_nrst : in std_logic;
22
    i_e_valid : in std_logic;                                         -- Execution stage outputs are valid
23
    i_e_pc : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);          -- Execution stage instruction pointer
24
    i_e_instr : in std_logic_vector(31 downto 0);                     -- Execution stage instruction value
25
 
26
    i_res_addr : in std_logic_vector(4 downto 0);                     -- Register address to be written (0=no writing)
27
    i_res_data : in std_logic_vector(RISCV_ARCH-1 downto 0);          -- Register value to be written
28
    i_memop_sign_ext : in std_logic;                                  -- Load data with sign extending (if less than 8 Bytes)
29
    i_memop_load : in std_logic;                                      -- Load data from memory and write to i_res_addr
30
    i_memop_store : in std_logic;                                     -- Store i_res_data value into memory
31
    i_memop_size : in std_logic_vector(1 downto 0);                   -- Encoded memory transaction size in bytes: 0=1B; 1=2B; 2=4B; 3=8B
32
    i_memop_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);    -- Memory access address
33
    o_wena : out std_logic;                                           -- Write enable signal
34
    o_waddr : out std_logic_vector(4 downto 0);                       -- Output register address (0 = x0 = no write)
35
    o_wdata : out std_logic_vector(RISCV_ARCH-1 downto 0);            -- Register value
36
 
37
    -- Memory interface:
38
    i_mem_req_ready : in std_logic;
39
    o_mem_valid : out std_logic;                                      -- Memory request is valid
40
    o_mem_write : out std_logic;                                      -- Memory write request
41
    o_mem_sz : out std_logic_vector(1 downto 0);                      -- Encoded data size in bytes: 0=1B; 1=2B; 2=4B; 3=8B
42
    o_mem_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);     -- Data path requested address
43
    o_mem_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0);     -- Data path requested data (write transaction)
44
    i_mem_data_valid : in std_logic;                                  -- Data path memory response is valid
45
    i_mem_data_addr : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); -- Data path memory response address
46
    i_mem_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0);      -- Data path memory response value
47
    o_mem_resp_ready : out std_logic;
48
 
49
    o_hold : out std_logic;                                           -- Memory operation is more than 1 clock
50
    o_valid : out std_logic;                                          -- Output is valid
51
    o_pc : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);           -- Valid instruction pointer
52
    o_instr : out std_logic_vector(31 downto 0)                       -- Valid instruction value
53
  );
54
end;
55
 
56
architecture arch_MemAccess of MemAccess is
57
 
58
  type RegistersType is record
59
      valid : std_logic;
60
      pc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
61
      instr : std_logic_vector(31 downto 0);
62
 
63
      wena : std_logic;
64
      waddr : std_logic_vector(4 downto 0);
65
      sign_ext : std_logic;
66
      size : std_logic_vector(1 downto 0);
67
      wdata : std_logic_vector(RISCV_ARCH-1 downto 0);
68
      wait_req : std_logic;
69
      wait_req_write : std_logic;
70
      wait_req_sz : std_logic_vector(1 downto 0);
71
      wait_req_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
72
      wait_req_wdata : std_logic_vector(RISCV_ARCH-1 downto 0);
73
      wait_resp : std_logic;
74
  end record;
75
 
76
  signal r, rin : RegistersType;
77
 
78
begin
79
 
80
 
81
  comb : process(i_nrst, i_mem_req_ready, i_e_valid, i_e_pc, i_e_instr, i_res_addr, i_res_data,
82
                i_memop_sign_ext, i_memop_load, i_memop_store, i_memop_size,
83
                i_memop_addr, i_mem_data_valid, i_mem_data_addr, i_mem_data, r)
84
    variable v : RegistersType;
85
    variable w_req_fire : std_logic;
86
    variable w_o_mem_valid : std_logic;
87
    variable w_o_mem_write : std_logic;
88
    variable wb_o_mem_sz : std_logic_vector(1 downto 0);
89
    variable wb_o_mem_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
90
    variable wb_o_mem_wdata : std_logic_vector(RISCV_ARCH-1 downto 0);
91
    variable wb_res_wdata : std_logic_vector(RISCV_ARCH-1 downto 0);
92
    variable w_memop : std_logic;
93
    variable w_o_valid : std_logic;
94
    variable w_o_wena : std_logic;
95
    variable w_o_hold : std_logic;
96
    variable w_mem_fire : std_logic;
97
  begin
98
 
99
    v := r;
100
 
101
    w_o_mem_valid := '0';
102
    w_o_mem_write := '0';
103
    wb_o_mem_sz := (others => '0');
104
    wb_o_mem_addr := (others => '0');
105
    wb_o_mem_wdata := (others => '0');
106
    v.valid := '0';
107
    w_o_hold := '0';
108
 
109
    w_memop := i_memop_load or i_memop_store;
110
 
111
    if r.wait_req = '1' then
112
        if i_mem_req_ready = '1' then
113
            v.wait_req := '0';
114
            v.wait_resp := '1';
115
        end if;
116
        w_o_mem_valid := '1';
117
        w_o_mem_write := r.wait_req_write;
118
        wb_o_mem_sz := r.wait_req_sz;
119
        wb_o_mem_addr := r.wait_req_addr;
120
        wb_o_mem_wdata := r.wait_req_wdata;
121
    elsif i_e_valid = '1' then
122
      v.valid := not w_memop;
123
      v.pc := i_e_pc;
124
      v.instr := i_e_instr;
125
      v.waddr := i_res_addr;
126
      v.wdata := i_res_data;
127
      if i_res_addr = "00000" then
128
          v.wena := '0';
129
      else
130
          v.wena := '1';
131
      end if;
132
 
133
      if w_memop = '1' then
134
        w_o_mem_valid := '1';
135
        w_o_mem_write := i_memop_store;
136
        wb_o_mem_sz := i_memop_size;
137
        wb_o_mem_addr := i_memop_addr;
138
        wb_o_mem_wdata := i_res_data;
139
        v.sign_ext := i_memop_sign_ext;
140
        v.size := i_memop_size;
141
 
142
        v.wait_resp := i_mem_req_ready;
143
        v.wait_req := not i_mem_req_ready;
144
        v.wait_req_write := i_memop_store;
145
        v.wait_req_sz := i_memop_size;
146
        v.wait_req_addr := i_memop_addr;
147
        v.wait_req_wdata := i_res_data;
148
      else
149
        w_o_mem_valid := '0';
150
        w_o_mem_write := '0';
151
        wb_o_mem_sz := (others => '0');
152
        wb_o_mem_addr := (others => '0');
153
        wb_o_mem_wdata := (others => '0');
154
        v.sign_ext := '0';
155
        v.size := (others => '0');
156
        v.wait_req_addr := (others => '0');
157
        v.wait_req := '0';
158
        v.wait_resp := '0';
159
      end if;
160
    elsif i_mem_data_valid = '1' then
161
      v.wait_resp := '0';
162
    end if;
163
 
164
    w_o_hold := (i_e_valid and w_memop) or r.wait_req
165
            or (r.wait_resp and not i_mem_data_valid);
166
 
167
    w_mem_fire := i_mem_data_valid;
168
 
169
    if w_mem_fire = '1' then
170
        if r.sign_ext = '1' then
171
            case r.size is
172
            when MEMOP_1B =>
173
                wb_res_wdata := i_mem_data;
174
                wb_res_wdata(63 downto 8) := (others => i_mem_data(7));
175
            when MEMOP_2B =>
176
                wb_res_wdata := i_mem_data;
177
                wb_res_wdata(63 downto 16) := (others => i_mem_data(15));
178
            when MEMOP_4B =>
179
                wb_res_wdata := i_mem_data;
180
                wb_res_wdata(63 downto 32) := (others => i_mem_data(31));
181
            when others =>
182
                wb_res_wdata := i_mem_data;
183
            end case;
184
        else
185
            wb_res_wdata := i_mem_data;
186
        end if;
187
    else
188
        wb_res_wdata := r.wdata;
189
    end if;
190
 
191
    w_o_valid := r.valid or w_mem_fire;
192
    w_o_wena := r.wena and w_o_valid;
193
 
194
    if i_nrst = '0' then
195
        v.valid := '0';
196
        v.pc := (others => '0');
197
        v.instr := (others => '0');
198
        v.waddr := (others => '0');
199
        v.wdata := (others => '0');
200
        v.wena := '0';
201
        v.size := (others => '0');
202
        v.sign_ext := '0';
203
        v.wait_req := '0';
204
        v.wait_req_write := '0';
205
        v.wait_req_sz := (others => '0');
206
        v.wait_req_addr := (others => '0');
207
        v.wait_req_wdata := (others => '0');
208
        v.wait_resp := '0';
209
    end if;
210
 
211
    o_mem_resp_ready <= '1';
212
 
213
    o_mem_valid <= w_o_mem_valid;
214
    o_mem_write <= w_o_mem_write;
215
    o_mem_sz <= wb_o_mem_sz;
216
    o_mem_addr <= wb_o_mem_addr;
217
    o_mem_data <= wb_o_mem_wdata;
218
 
219
    o_wena <= w_o_wena;
220
    o_waddr <= r.waddr;
221
    o_wdata <= wb_res_wdata;
222
    o_valid <= w_o_valid;
223
    o_pc <= r.pc;
224
    o_instr <= r.instr;
225
    o_hold <= w_o_hold;
226
 
227
    rin <= v;
228
  end process;
229
 
230
  -- registers:
231
  regs : process(i_clk)
232
  begin
233
     if rising_edge(i_clk) then
234
        r <= rin;
235
     end if;
236
  end process;
237
 
238
end;

powered by: WebSVN 2.1.0

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