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

Subversion Repositories marca

[/] [marca/] [tags/] [INITIAL/] [vhdl/] [mem.vhd] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jeunes2
--  This file is part of the marca processor.
2
--  Copyright (C) 2007 Wolfgang Puffitsch
3
 
4
--  This program is free software; you can redistribute it and/or modify it
5
--  under the terms of the GNU Library General Public License as published
6
--  by the Free Software Foundation; either version 2, or (at your option)
7
--  any later version.
8
 
9
--  This program is distributed in the hope that it will be useful,
10
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
--  Library General Public License for more details.
13
 
14
--  You should have received a copy of the GNU Library General Public
15
--  License along with this program; if not, write to the Free Software
16
--  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
17
 
18
-------------------------------------------------------------------------------
19
-- MARCA fetch stage
20
-------------------------------------------------------------------------------
21
-- architecture for the instruction-fetch pipeline stage
22
-------------------------------------------------------------------------------
23
 
24
-------------------------------------------------------------------------------
25
-- Wolfgang Puffitsch
26
-- Computer Architecture Lab, Group 3
27
-------------------------------------------------------------------------------
28
 
29
library IEEE;
30
use IEEE.std_logic_1164.all;
31
use IEEE.numeric_std.all;
32
 
33
use work.marca_pkg.all;
34
use work.sc_pkg.all;
35
 
36
architecture behaviour of mem is
37
 
38
type WAIT_STATE is (WAIT_LOAD_EVEN,  WAIT_LOAD_ODD,
39
                    WAIT_LOADL_EVEN, WAIT_LOADL_ODD,
40
                    WAIT_LOADH_EVEN, WAIT_LOADH_ODD,
41
                    WAIT_LOADB_EVEN, WAIT_LOADB_ODD,
42
                    WAIT_STORE,
43
                    WAIT_NONE);
44
 
45
signal state      : WAIT_STATE;
46
signal next_state : WAIT_STATE;
47
 
48
signal old_data   : std_logic_vector(REG_WIDTH-1 downto 0);
49
signal next_data  : std_logic_vector(REG_WIDTH-1 downto 0);
50
 
51
component data_memory
52
  port (
53
    clken   : in  std_logic;
54
    clock   : in  std_logic;
55
    wren    : in  std_logic;
56
    address : in  std_logic_vector (ADDR_WIDTH-2 downto 0);
57
    data    : in  std_logic_vector (DATA_WIDTH-1 downto 0);
58
    q       : out std_logic_vector (DATA_WIDTH-1 downto 0));
59
end component;
60
 
61
signal ram_enable : std_logic;
62
 
63
signal wren0 : std_logic;
64
signal a0 : std_logic_vector(ADDR_WIDTH-2 downto 0);
65
signal d0 : std_logic_vector(DATA_WIDTH-1 downto 0);
66
signal q0 : std_logic_vector(DATA_WIDTH-1 downto 0);
67
 
68
signal wren1 : std_logic;
69
signal a1 : std_logic_vector(ADDR_WIDTH-2 downto 0);
70
signal d1 : std_logic_vector(DATA_WIDTH-1 downto 0);
71
signal q1 : std_logic_vector(DATA_WIDTH-1 downto 0);
72
 
73
component data_rom
74
  generic (
75
    init_file : string);
76
  port (
77
    clken   : in  std_logic;
78
    clock   : in  std_logic;
79
    address : in  std_logic_vector (RADDR_WIDTH-2 downto 0);
80
    q       : out std_logic_vector (RDATA_WIDTH-1 downto 0));
81
end component;
82
 
83
signal rom_enable : std_logic;
84
 
85
signal ra0 : std_logic_vector(RADDR_WIDTH-2 downto 0);
86
signal rq0 : std_logic_vector(RDATA_WIDTH-1 downto 0);
87
 
88
signal ra1 : std_logic_vector(RADDR_WIDTH-2 downto 0);
89
signal rq1 : std_logic_vector(RDATA_WIDTH-1 downto 0);
90
 
91
 
92
signal sc_input  : SC_IN;
93
signal sc_output : SC_OUT;
94
 
95
component sc_uart
96
  generic (
97
    clock_freq : integer;
98
    baud_rate  : integer;
99
    txf_depth  : integer; txf_thres  : integer;
100
    rxf_depth  : integer; rxf_thres  : integer);
101
  port (
102
    clock  : in  std_logic;
103
    reset  : in  std_logic;
104
    input  : in  SC_IN;
105
    output : out SC_OUT;
106
    intr   : out std_logic;
107
    txd    : out std_logic;
108
    rxd    : in  std_logic;
109
    nrts   : out std_logic;
110
    ncts   : in  std_logic);
111
end component;
112
 
113
signal uart_input  : SC_IN;
114
signal uart_output : SC_OUT;
115
 
116
begin  -- behaviour
117
 
118
  intrs(VEC_COUNT-1 downto 4) <= (others => '0');
119
 
120
  data_memory_0_unit : data_memory
121
    port map (
122
      clken     => ram_enable,
123
      clock     => clock,
124
      wren      => wren0,
125
      address   => a0,
126
      data      => d0,
127
      q         => q0);
128
 
129
  data_memory_1_unit : data_memory
130
    port map (
131
      clken     => ram_enable,
132
      clock     => clock,
133
      wren      => wren1,
134
      address   => a1,
135
      data      => d1,
136
      q         => q1);
137
 
138
  data_rom_0_unit : data_rom
139
    generic map (
140
      init_file => "../vhdl/rom0.mif")
141
    port map (
142
      clken     => rom_enable,
143
      clock     => clock,
144
      address   => ra0,
145
      q         => rq0);
146
 
147
  data_rom_1_unit : data_rom
148
    generic map (
149
      init_file => "../vhdl/rom1.mif")
150
    port map (
151
      clken     => rom_enable,
152
      clock     => clock,
153
      address   => ra1,
154
      q         => rq1);
155
 
156
  uart_unit : sc_uart
157
    generic map (
158
      clock_freq => CLOCK_FREQ,
159
      baud_rate => UART_BAUD_RATE,
160
      txf_depth => 2, txf_thres => 1,
161
      rxf_depth => 2, rxf_thres => 1)
162
    port map (
163
      clock => clock,
164
      reset => reset,
165
      input => uart_input,
166
      output => uart_output,
167
      intr => intrs(UART_INTR),
168
      txd => ext_out(UART_TXD),
169
      rxd => ext_in(UART_RXD),
170
      nrts => ext_out(UART_NRTS),
171
      ncts => ext_in(UART_NCTS));
172
 
173
  syn_proc: process (clock, reset)
174
  begin  -- process syn_proc
175
    if reset = RESET_ACTIVE then                 -- asynchronous reset (active low)
176
      state <= WAIT_NONE;
177
      old_data <= (others => '0');
178
    elsif clock'event and clock = '1' then  -- rising clock edge
179
      state <= next_state;
180
      old_data <= next_data;
181
    end if;
182
  end process syn_proc;
183
 
184
  business: process (next_state)
185
  begin  -- process business
186
    if next_state /= WAIT_NONE then
187
      busy <= '1';
188
    else
189
      busy <= '0';
190
    end if;
191
  end process business;
192
 
193
  sc_mux: process (address, sc_input,
194
                   uart_output)
195
  begin  -- process sc_mux
196
 
197
    uart_input <= SC_IN_NULL;
198
    sc_output  <= SC_OUT_NULL;
199
 
200
    case address(REG_WIDTH-1 downto SC_ADDR_WIDTH+1) is
201
      when UART_BASE_ADDR =>
202
        uart_input <= sc_input;
203
        sc_output <= uart_output;
204
      when others => null;
205
    end case;
206
 
207
  end process sc_mux;
208
 
209
  readwrite: process (state, op, address, data, old_data, q0, q1, rq0, rq1, sc_output)
210
  begin  -- process readwrite
211
    exc <= '0';
212
 
213
    ram_enable <= '0';
214
 
215
    wren0 <= '0';
216
    wren1 <= '0';
217
 
218
    a0 <= (others => '0');
219
    d0 <= (others => '0');
220
 
221
    a1 <= (others => '0');
222
    d1 <= (others => '0');
223
 
224
    rom_enable <= '0';
225
 
226
    ra0 <= (others => '0');
227
    ra1 <= (others => '0');
228
 
229
    sc_input <= SC_IN_NULL;
230
 
231
    result <= (others => '0');
232
 
233
    next_state <= WAIT_NONE;
234
    next_data <= data;
235
 
236
    if unsigned(address) >= unsigned(MEM_MIN_ADDR)
237
      and unsigned(address) <= unsigned(MEM_MAX_ADDR) then
238
 
239
      -- regular memory access
240
      if op /= MEM_NOP then
241
        ram_enable <= '1';
242
      end if;
243
 
244
      case state is
245
        when WAIT_LOAD_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= q1;
246
                               result(REG_WIDTH/2-1 downto 0) <= q0;
247
                               next_state <= WAIT_NONE;
248
 
249
        when WAIT_LOAD_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= q0;
250
                              result(REG_WIDTH/2-1 downto 0) <= q1;
251
                              next_state <= WAIT_NONE;
252
 
253
        when WAIT_LOADL_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= old_data(REG_WIDTH-1 downto REG_WIDTH/2);
254
                                result(REG_WIDTH/2-1 downto 0) <= q0;
255
                                next_state <= WAIT_NONE;
256
 
257
        when WAIT_LOADL_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= old_data(REG_WIDTH-1 downto REG_WIDTH/2);
258
                               result(REG_WIDTH/2-1 downto 0) <= q1;
259
                               next_state <= WAIT_NONE;
260
 
261
        when WAIT_LOADH_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= q0;
262
                                result(REG_WIDTH/2-1 downto 0) <= old_data(REG_WIDTH/2-1 downto 0);
263
                                next_state <= WAIT_NONE;
264
 
265
        when WAIT_LOADH_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= q1;
266
                               result(REG_WIDTH/2-1 downto 0) <= old_data(REG_WIDTH/2-1 downto 0);
267
                               next_state <= WAIT_NONE;
268
 
269
        when WAIT_LOADB_EVEN => result <= std_logic_vector(resize(signed(q0), REG_WIDTH));
270
                                next_state <= WAIT_NONE;
271
 
272
        when WAIT_LOADB_ODD => result <= std_logic_vector(resize(signed(q1), REG_WIDTH));
273
                               next_state <= WAIT_NONE;
274
 
275
        when WAIT_NONE =>
276
          case op is
277
            when MEM_LOAD => if address(0) = '0' then
278
                               a0 <= address(ADDR_WIDTH-1 downto 1);
279
                               a1 <= address(ADDR_WIDTH-1 downto 1);
280
                               next_state <= WAIT_LOAD_EVEN;
281
                             else
282
                               a1 <= address(ADDR_WIDTH-1 downto 1);
283
                               a0 <= std_logic_vector(unsigned(address(ADDR_WIDTH-1 downto 1)) + 1);
284
                               next_state <= WAIT_LOAD_ODD;
285
                             end if;
286
            when MEM_LOADL => if address(0) = '0' then
287
                                a0 <= address(ADDR_WIDTH-1 downto 1);
288
                                next_state <= WAIT_LOADL_EVEN;
289
                              else
290
                                a1 <= address(ADDR_WIDTH-1 downto 1);
291
                                next_state <= WAIT_LOADL_ODD;
292
                              end if;
293
            when MEM_LOADH => if address(0) = '0' then
294
                                a0 <= address(ADDR_WIDTH-1 downto 1);
295
                                next_state <= WAIT_LOADH_EVEN;
296
                              else
297
                                a1 <= address(ADDR_WIDTH-1 downto 1);
298
                                next_state <= WAIT_LOADH_ODD;
299
                              end if;
300
            when MEM_LOADB => if address(0) = '0' then
301
                                a0 <= address(ADDR_WIDTH-1 downto 1);
302
                                next_state <= WAIT_LOADB_EVEN;
303
                              else
304
                                a1 <= address(ADDR_WIDTH-1 downto 1);
305
                                next_state <= WAIT_LOADB_ODD;
306
                              end if;
307
            when MEM_STORE => if address(0) = '0' then
308
                                wren0 <= '1';
309
                                wren1 <= '1';
310
                                a0 <= address(ADDR_WIDTH-1 downto 1);
311
                                a1 <= address(ADDR_WIDTH-1 downto 1);
312
                                d0 <= data(REG_WIDTH/2-1 downto 0);
313
                                d1 <= data(REG_WIDTH-1 downto REG_WIDTH/2);
314
                                next_state <= WAIT_NONE;
315
                              else
316
                                wren0 <= '1';
317
                                wren1 <= '1';
318
                                a1 <= address(ADDR_WIDTH-1 downto 1);
319
                                a0 <= std_logic_vector(unsigned(address(ADDR_WIDTH-1 downto 1)) + 1);
320
                                d1 <= data(REG_WIDTH/2-1 downto 0);
321
                                d0 <= data(REG_WIDTH-1 downto REG_WIDTH/2);
322
                                next_state <= WAIT_NONE;
323
                              end if;
324
            when MEM_STOREL => if address(0) = '0' then
325
                                 wren0 <= '1';
326
                                 a0 <= address(ADDR_WIDTH-1 downto 1);
327
                                 d0 <= data(REG_WIDTH/2-1 downto 0);
328
                                 next_state <= WAIT_NONE;
329
                               else
330
                                 wren1 <= '1';
331
                                 a1 <= address(ADDR_WIDTH-1 downto 1);
332
                                 d1 <= data(REG_WIDTH/2-1 downto 0);
333
                                 next_state <= WAIT_NONE;
334
                               end if;
335
            when MEM_STOREH => if address(0) = '0' then
336
                                 wren0 <= '1';
337
                                 a0 <= address(ADDR_WIDTH-1 downto 1);
338
                                 d0 <= data(REG_WIDTH-1 downto REG_WIDTH/2);
339
                                 next_state <= WAIT_NONE;
340
                               else
341
                                 wren1 <= '1';
342
                                 a1 <= address(ADDR_WIDTH-1 downto 1);
343
                                 d1 <= data(REG_WIDTH-1 downto REG_WIDTH/2);
344
                                 next_state <= WAIT_NONE;
345
                               end if;
346
            when MEM_NOP => next_state <= WAIT_NONE;
347
            when others => null;
348
          end case;
349
        when others => null;
350
      end case;
351
 
352
    elsif unsigned(address) >= unsigned(ROM_MIN_ADDR)
353
      and unsigned(address) <= unsigned(ROM_MAX_ADDR) then
354
 
355
      -- accessing the ROM
356
      if op /= MEM_NOP then
357
        rom_enable <= '1';
358
      end if;
359
 
360
      case state is
361
        when WAIT_LOAD_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= rq1;
362
                               result(REG_WIDTH/2-1 downto 0) <= rq0;
363
                               next_state <= WAIT_NONE;
364
 
365
        when WAIT_LOAD_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= rq0;
366
                              result(REG_WIDTH/2-1 downto 0) <= rq1;
367
                              next_state <= WAIT_NONE;
368
 
369
        when WAIT_LOADL_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= old_data(REG_WIDTH-1 downto REG_WIDTH/2);
370
                                result(REG_WIDTH/2-1 downto 0) <= rq0;
371
                                next_state <= WAIT_NONE;
372
 
373
        when WAIT_LOADL_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= old_data(REG_WIDTH-1 downto REG_WIDTH/2);
374
                               result(REG_WIDTH/2-1 downto 0) <= rq1;
375
                               next_state <= WAIT_NONE;
376
 
377
        when WAIT_LOADH_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= rq0;
378
                                result(REG_WIDTH/2-1 downto 0) <= old_data(REG_WIDTH/2-1 downto 0);
379
                                next_state <= WAIT_NONE;
380
 
381
        when WAIT_LOADH_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= rq1;
382
                               result(REG_WIDTH/2-1 downto 0) <= old_data(REG_WIDTH/2-1 downto 0);
383
                               next_state <= WAIT_NONE;
384
 
385
        when WAIT_LOADB_EVEN => result <= std_logic_vector(resize(signed(rq0), REG_WIDTH));
386
                                next_state <= WAIT_NONE;
387
 
388
        when WAIT_LOADB_ODD => result <= std_logic_vector(resize(signed(rq1), REG_WIDTH));
389
                               next_state <= WAIT_NONE;
390
 
391
        when WAIT_NONE =>
392
          case op is
393
            when MEM_LOAD => if address(0) = '0' then
394
                               ra0 <= address(RADDR_WIDTH-1 downto 1);
395
                               ra1 <= address(RADDR_WIDTH-1 downto 1);
396
                               next_state <= WAIT_LOAD_EVEN;
397
                             else
398
                               ra1 <= address(RADDR_WIDTH-1 downto 1);
399
                               ra0 <= std_logic_vector(unsigned(address(RADDR_WIDTH-1 downto 1)) + 1);
400
                               next_state <= WAIT_LOAD_ODD;
401
                             end if;
402
            when MEM_LOADL => if address(0) = '0' then
403
                                ra0 <= address(RADDR_WIDTH-1 downto 1);
404
                                next_state <= WAIT_LOADL_EVEN;
405
                              else
406
                                ra1 <= address(RADDR_WIDTH-1 downto 1);
407
                                next_state <= WAIT_LOADL_ODD;
408
                              end if;
409
            when MEM_LOADH => if address(0) = '0' then
410
                                ra0 <= address(RADDR_WIDTH-1 downto 1);
411
                                next_state <= WAIT_LOADH_EVEN;
412
                              else
413
                                ra1 <= address(RADDR_WIDTH-1 downto 1);
414
                                next_state <= WAIT_LOADH_ODD;
415
                              end if;
416
            when MEM_LOADB => if address(0) = '0' then
417
                                ra0 <= address(RADDR_WIDTH-1 downto 1);
418
                                next_state <= WAIT_LOADB_EVEN;
419
                              else
420
                                ra1 <= address(RADDR_WIDTH-1 downto 1);
421
                                next_state <= WAIT_LOADB_ODD;
422
                              end if;
423
            when MEM_NOP => next_state <= WAIT_NONE;
424
            when others => exc <= '1';  -- inhibit invalid operations
425
          end case;
426
        when others => null;
427
      end case;
428
 
429
    elsif unsigned(address) >= unsigned(SC_MIN_ADDR)
430
      and unsigned(address) <= unsigned(SC_MAX_ADDR)
431
      and address(0) = '0' then
432
 
433
      -- access via SimpCon interface
434
      case state is
435
 
436
        when WAIT_LOAD_EVEN =>
437
          if sc_output.rdy_cnt /= "00" then
438
            next_state <= WAIT_LOAD_EVEN;
439
          else
440
            result <= sc_output.rd_data;
441
            next_state <= WAIT_NONE;
442
          end if;
443
 
444
        when WAIT_STORE =>
445
          if sc_output.rdy_cnt /= "00" then
446
            next_state <= WAIT_STORE;
447
          else
448
            next_state <= WAIT_NONE;
449
          end if;
450
 
451
        when WAIT_NONE =>
452
          case op is
453
 
454
            when MEM_LOAD =>
455
              sc_input.address <= address(SC_ADDR_WIDTH downto 1);
456
              sc_input.wr      <= '0';
457
              sc_input.wr_data <= (others => '0');
458
              sc_input.rd      <= '1';
459
              next_state <= WAIT_LOAD_EVEN;
460
 
461
            when MEM_STORE =>
462
              sc_input.address <= address(SC_ADDR_WIDTH downto 1);
463
              sc_input.wr      <= '1';
464
              sc_input.wr_data <= data;
465
              sc_input.rd      <= '0';
466
              next_state <= WAIT_STORE;
467
 
468
            when MEM_NOP => next_state <= WAIT_NONE;
469
 
470
            when others => exc <= '1';   -- inhibit invalid operations
471
 
472
          end case;
473
        when others => null;
474
      end case;
475
 
476
    else
477
      -- invalid address and/or alignment
478
      if op /= MEM_NOP then
479
        exc <= '1';
480
      end if;
481
    end if;
482
 
483
  end process readwrite;
484
 
485
end behaviour;

powered by: WebSVN 2.1.0

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