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

Subversion Repositories tinycpu

[/] [tinycpu/] [trunk/] [src/] [memory.vhd] - Blame information for rev 41

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 earlz
--Memory management component
2
--By having this separate, it should be fairly easy to add RAMs or ROMs later
3
--This basically lets the CPU not have to worry about how memory "Really" works
4
--currently just one RAM. 1024 byte blockram.vhd mapped as 0 - 1023
5 6 earlz
 
6 4 earlz
library IEEE;
7
use IEEE.STD_LOGIC_1164.ALL;
8
use IEEE.NUMERIC_STD.ALL;
9
 
10 6 earlz
 
11
 
12 4 earlz
entity memory is
13
  port(
14 18 earlz
    Address: in std_logic_vector(15 downto 0); --memory address (in bytes)
15
    WriteWord: in std_logic; --if set, will write a full 16-bit word instead of a byte. Address must be aligned to 16-bit address. (bottom bit must be 0)
16
    WriteEnable: in std_logic;
17 4 earlz
    Clock: in std_logic;
18
    DataIn: in std_logic_vector(15 downto 0);
19 37 earlz
    DataOut: out std_logic_vector(15 downto 0);
20
 
21
    Port0: inout std_logic_vector(7 downto 0)
22 18 earlz
--    Reset: in std_logic
23
 
24
    --RAM/ROM interface (RAMA is built in to here
25
    --RAMBDataIn: out std_logic_vector(15 downto 0);
26
    --RAMBDataOut: in std_logic_vector(15 downto 0);
27
    --RAMBAddress: out std_logic_vector(15 downto 0);
28
    --RAMBWriteEnable: out std_logic_vector(1 downto 0);
29 4 earlz
  );
30
end memory;
31
 
32
architecture Behavioral of memory is
33 18 earlz
 
34
  component blockram
35
    port(
36
      Address: in std_logic_vector(7 downto 0); --memory address
37
      WriteEnable: in std_logic_vector(1 downto 0); --write or read
38
      Enable: in std_logic;
39
      Clock: in std_logic;
40
      DataIn: in std_logic_vector(15 downto 0);
41
      DataOut: out std_logic_vector(15 downto 0)
42
    );
43
  end component;
44
 
45 37 earlz
  constant R1START: integer := 15;
46
  constant R1END: integer := 1023+15;
47 18 earlz
  signal addr: std_logic_vector(15 downto 0) := (others => '0');
48
  signal R1addr: std_logic_vector(7 downto 0);
49
  signal we: std_logic_vector(1 downto 0);
50
  signal datawrite: std_logic_vector(15 downto 0);
51
  signal dataread: std_logic_vector(15 downto 0);
52
  --signal en: std_logic;
53
  signal R1we: std_logic_vector(1 downto 0);
54
  signal R1en: std_logic;
55
  signal R1in: std_logic_vector(15 downto 0);
56
  signal R1out: std_logic_vector(15 downto 0);
57 37 earlz
 
58
  signal port0we: std_logic_vector(7 downto 0);
59
  signal port0temp: std_logic_vector(7 downto 0);
60 4 earlz
begin
61 18 earlz
  R1: blockram port map (R1addr, R1we, R1en, Clock, R1in, R1out);
62
  addrwe: process(Address, WriteWord, WriteEnable, DataIn)
63 4 earlz
  begin
64 18 earlz
    addr <= Address(15 downto 1) & '0';
65
    if WriteEnable='1' then
66
      if WriteWord='1' then
67
        we <= "11";
68
        datawrite <= DataIn;
69
      else
70
        if Address(0)='0' then
71
          we <= "01";
72
          datawrite <= x"00" & DataIn(7 downto 0); --not really necessary
73
        else
74
          we <= "10";
75
          datawrite <= DataIn(7 downto 0) & x"00";
76 4 earlz
        end if;
77
      end if;
78 18 earlz
    else
79 19 earlz
      datawrite <= x"0000";
80 18 earlz
      we <= "00";
81 4 earlz
    end if;
82
  end process;
83 18 earlz
 
84 41 earlz
  assignram: process (we, datawrite, addr, r1out, port0, WriteEnable, Address, Clock, port0temp, port0we, DataIn)
85 18 earlz
  variable tmp: integer;
86 37 earlz
  variable tmp2: integer;
87 18 earlz
  variable found: boolean := false;
88 4 earlz
  begin
89 18 earlz
    tmp := to_integer(unsigned(addr));
90 37 earlz
    tmp2 := to_integer(unsigned(Address));
91
    if tmp2 <= 15 then --internal registers/mapped IO
92 38 earlz
      if rising_edge(Clock) then
93
        if WriteWord='0' then
94
          if tmp2=0 then
95 41 earlz
            --dataread <= x"0000";
96 38 earlz
 
97
            gen: for I in 0 to 7 loop
98
              if WriteEnable='1' then
99
                if port0we(I)='1' then --1-bit port set to WRITE mode
100 41 earlz
 
101
                  Port0(I) <= DataIn(I);
102
                  if I=0 then
103
                   -- report string(DataIn(I));
104
                    --assert(DataIn(I)='1') report "XXXXX" severity note;
105
                    --port0(I) <= '1';
106
                  end if;
107 38 earlz
                  port0temp(I) <= DataIn(I);
108 41 earlz
                  --dataread(I) <= DataIn(I);
109 38 earlz
                else
110
                  port0(I) <= 'Z';
111 41 earlz
                  port0temp(I) <= '0';
112
                  --dataread(I) <= port0(I);
113 38 earlz
                end if;
114
              else --not WE
115
                if port0we(I)='0' then --1-bit-port set to READ mode
116 41 earlz
                  --dataread(I) <= port0(I);
117 38 earlz
                else
118 41 earlz
                  --dataread(I) <= port0temp(I);
119 38 earlz
                end if;
120
              end if;
121
            end loop gen;
122
          elsif tmp2=1 then
123 41 earlz
            --dataread <= x"00" & port0we;
124 37 earlz
            if WriteEnable='1' then
125 38 earlz
              port0we <= DataIn(7 downto 0);
126 41 earlz
              --dataread<=x"00" & DataIn(7 downto 0);
127 38 earlz
              setwe: for I in 0 to 7 loop
128
                if DataIn(I)='0' then
129
                  port0(I) <= 'Z';
130
                end if;
131
              end loop setwe;
132
            else
133 41 earlz
              --dataread <= x"00" & port0we;
134 37 earlz
            end if;
135
          else
136 38 earlz
            --synthesis off
137
            report "Memory address is outside of bounds of RAM and registers" severity warning;
138
            --synthesis on
139 37 earlz
          end if;
140 38 earlz
 
141 37 earlz
        else
142
          --synthesis off
143 38 earlz
          report "WriteWord is not allowed in register area. Ignoring access" severity warning;
144 37 earlz
          --synthesis on
145
        end if;
146
      end if;
147 41 earlz
      dataread <= x"0000";
148
      outgen: for I in 0 to 7 loop
149
        if tmp2=0 then
150
          if port0we(I)='1' then
151
            if WriteEnable='1' then
152
              dataread(I) <= DataIn(I);
153
            else
154
              dataread(I) <= port0temp(I);
155
            end if;
156
          else
157
            dataread(I) <= port0(I);
158
          end if;
159
        elsif tmp2=0 then
160
          if WriteEnable='1' then
161
            dataread(I) <= DataIn(I);
162
          else
163
            dataread(I) <= port0we(I);
164
          end if;
165
        else
166
          dataread(I) <= '0';
167
        end if;
168
      end loop outgen;
169 38 earlz
      R1en <= '0';
170
      R1we <= "00";
171
      R1in <= x"0000";
172
      R1addr <= x"00";
173 37 earlz
    elsif tmp >= R1START and tmp <= R1END then --RAM bank1
174 18 earlz
      --map all to R1
175
      found := true;
176
      R1en <= '1';
177
      R1we <= we;
178
      R1in <= datawrite;
179
      dataread <= R1out;
180
      R1addr <= addr(8 downto 1);
181
    else
182
      R1en <= '0';
183
      R1we <= "00";
184
      R1in <= x"0000";
185
      R1addr <= x"00";
186
      dataread <= x"0000";
187 4 earlz
    end if;
188
  end process;
189 18 earlz
 
190
  readdata: process(Address, dataread)
191
  begin
192 41 earlz
    if to_integer(unsigned(Address))>15 then
193
      if Address(0) = '0' then
194
        DataOut <= dataread;
195
      else
196
        DataOut <= x"00" & dataread(15 downto 8);
197
      end if;
198 18 earlz
    else
199 41 earlz
      DataOut <= x"00" & dataread(7 downto 0);
200 18 earlz
    end if;
201
  end process;
202 4 earlz
end Behavioral;

powered by: WebSVN 2.1.0

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