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

Subversion Repositories mlite

[/] [mlite/] [trunk/] [vhdl/] [ram.vhd] - Blame information for rev 128

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rhoads
---------------------------------------------------------------------
2
-- TITLE: Random Access Memory
3
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4
-- DATE CREATED: 4/21/01
5
-- FILENAME: ram.vhd
6 43 rhoads
-- PROJECT: Plasma CPU core
7 2 rhoads
-- COPYRIGHT: Software placed into the public domain by the author.
8
--    Software 'as is' without warranty.  Author liable for nothing.
9
-- DESCRIPTION:
10 48 rhoads
--    Implements the RAM, reads the executable from either "code.txt",
11
--    or for Altera "code[0-3].hex".
12 2 rhoads
--    Modified from "The Designer's Guide to VHDL" by Peter J. Ashenden
13
---------------------------------------------------------------------
14
library ieee;
15
use ieee.std_logic_1164.all;
16
use ieee.std_logic_misc.all;
17
use ieee.std_logic_arith.all;
18 85 rhoads
use ieee.std_logic_unsigned.all;
19 2 rhoads
use ieee.std_logic_textio.all;
20
use std.textio.all;
21 39 rhoads
use work.mlite_pack.all;
22 2 rhoads
 
23
entity ram is
24 48 rhoads
   generic(memory_type : string := "GENERIC");
25 2 rhoads
   port(clk          : in std_logic;
26
        mem_byte_sel : in std_logic_vector(3 downto 0);
27
        mem_write    : in std_logic;
28 48 rhoads
        mem_address  : in std_logic_vector(31 downto 0);
29 55 rhoads
        mem_data_w   : in std_logic_vector(31 downto 0);
30
        mem_data_r   : out std_logic_vector(31 downto 0));
31 2 rhoads
end; --entity ram
32
 
33
architecture logic of ram is
34 55 rhoads
   constant ADDRESS_WIDTH   : natural := 13;
35
   signal clk_inv           : std_logic;
36
   signal mem_sel           : std_logic;
37
   signal read_enable       : std_logic;
38 48 rhoads
   signal write_byte_enable : std_logic_vector(3 downto 0);
39 2 rhoads
begin
40 55 rhoads
   clk_inv <= not clk;
41 85 rhoads
   mem_sel <= '1' when mem_address(30 downto ADDRESS_WIDTH) = ZERO(30 downto ADDRESS_WIDTH) else
42 48 rhoads
              '0';
43
   read_enable <= mem_sel and not mem_write;
44
   write_byte_enable <= mem_byte_sel when mem_sel = '1' else
45
                        "0000";
46 2 rhoads
 
47 48 rhoads
   generic_ram:
48
   if memory_type = "GENERIC" generate
49
   ram_proc: process(clk, mem_byte_sel, mem_write,
50 55 rhoads
         mem_address, mem_data_w, mem_sel)
51 98 rhoads
      variable mem_size : natural := 2 ** ADDRESS_WIDTH;
52 48 rhoads
      variable data : std_logic_vector(31 downto 0);
53 55 rhoads
      subtype word is std_logic_vector(mem_data_w'length-1 downto 0);
54 48 rhoads
      type storage_array is
55 98 rhoads
         array(natural range 0 to mem_size/4 - 1) of word;
56 48 rhoads
      variable storage : storage_array;
57
      variable index : natural := 0;
58
      file load_file : text is in "code.txt";
59
      variable hex_file_line : line;
60
   begin
61 128 rhoads
 
62 48 rhoads
      --load in the ram executable image
63
      if index = 0 then
64
         while not endfile(load_file) loop
65 55 rhoads
--The following two lines had to be commented out for synthesis
66 48 rhoads
            readline(load_file, hex_file_line);
67
            hread(hex_file_line, data);
68
            storage(index) := data;
69
            index := index + 1;
70
         end loop;
71 2 rhoads
      end if;
72
 
73 55 rhoads
      index := conv_integer(mem_address(ADDRESS_WIDTH-1 downto 2));
74 2 rhoads
      data := storage(index);
75
 
76 48 rhoads
      if mem_sel = '1' then
77
         if mem_write = '0' then
78 55 rhoads
            mem_data_r <= data;
79 48 rhoads
         end if;
80
         if mem_byte_sel(0) = '1' then
81 55 rhoads
            data(7 downto 0) := mem_data_w(7 downto 0);
82 48 rhoads
         end if;
83
         if mem_byte_sel(1) = '1' then
84 55 rhoads
            data(15 downto 8) := mem_data_w(15 downto 8);
85 48 rhoads
         end if;
86
         if mem_byte_sel(2) = '1' then
87 55 rhoads
            data(23 downto 16) := mem_data_w(23 downto 16);
88 48 rhoads
         end if;
89
         if mem_byte_sel(3) = '1' then
90 55 rhoads
            data(31 downto 24) := mem_data_w(31 downto 24);
91 48 rhoads
         end if;
92 2 rhoads
      end if;
93
 
94
      if rising_edge(clk) then
95
         if mem_write = '1' then
96
            storage(index) := data;
97
         end if;
98
      end if;
99 48 rhoads
   end process;
100
   end generate; --generic_ram
101 2 rhoads
 
102 48 rhoads
 
103
   altera_ram:
104
   if memory_type = "ALTERA" generate
105 55 rhoads
      --Quartus II does not allow asynchronous RAM to be initialized
106
      --since the RAM may see glitches on the write enable during powerup.
107
      --Making lpm_address_control="REGISTERED" makes the RAM synchronous
108
      --but then the reads are delayed by a clock cycle.
109
      --Inverting the RAM clock appears to solve the clock cycle delay problem.
110
      lpm_ram_io_component0 : lpm_ram_dq
111 48 rhoads
         GENERIC MAP (
112
            intended_device_family => "UNUSED",
113
            lpm_width => 8,
114 55 rhoads
            lpm_widthad => ADDRESS_WIDTH-2,
115 48 rhoads
            lpm_indata => "REGISTERED",
116 55 rhoads
            lpm_address_control => "REGISTERED",
117 48 rhoads
            lpm_outdata => "UNREGISTERED",
118
            lpm_file => "code0.hex",
119
            use_eab => "ON",
120
            lpm_type => "LPM_RAM_DQ")
121
         PORT MAP (
122 55 rhoads
            data    => mem_data_w(31 downto 24),
123
            address => mem_address(ADDRESS_WIDTH-1 downto 2),
124
            inclock => clk_inv,
125 48 rhoads
            we      => write_byte_enable(3),
126 55 rhoads
            q       => mem_data_r(31 downto 24));
127 48 rhoads
 
128 55 rhoads
      lpm_ram_io_component1 : lpm_ram_dq
129 48 rhoads
         GENERIC MAP (
130
            intended_device_family => "UNUSED",
131
            lpm_width => 8,
132 55 rhoads
            lpm_widthad => ADDRESS_WIDTH-2,
133 48 rhoads
            lpm_indata => "REGISTERED",
134 55 rhoads
            lpm_address_control => "REGISTERED",
135 48 rhoads
            lpm_outdata => "UNREGISTERED",
136
            lpm_file => "code1.hex",
137
            use_eab => "ON",
138
            lpm_type => "LPM_RAM_DQ")
139
         PORT MAP (
140 55 rhoads
            data    => mem_data_w(23 downto 16),
141
            address => mem_address(ADDRESS_WIDTH-1 downto 2),
142
            inclock => clk_inv,
143 48 rhoads
            we      => write_byte_enable(2),
144 55 rhoads
            q       => mem_data_r(23 downto 16));
145 48 rhoads
 
146 55 rhoads
      lpm_ram_io_component2 : lpm_ram_dq
147 48 rhoads
         GENERIC MAP (
148
            intended_device_family => "UNUSED",
149
            lpm_width => 8,
150 55 rhoads
            lpm_widthad => ADDRESS_WIDTH-2,
151 48 rhoads
            lpm_indata => "REGISTERED",
152 55 rhoads
            lpm_address_control => "REGISTERED",
153 48 rhoads
            lpm_outdata => "UNREGISTERED",
154
            lpm_file => "code2.hex",
155
            use_eab => "ON",
156
            lpm_type => "LPM_RAM_DQ")
157
         PORT MAP (
158 55 rhoads
            data    => mem_data_w(15 downto 8),
159
            address => mem_address(ADDRESS_WIDTH-1 downto 2),
160
            inclock => clk_inv,
161 48 rhoads
            we      => write_byte_enable(1),
162 55 rhoads
            q       => mem_data_r(15 downto 8));
163 48 rhoads
 
164 55 rhoads
      lpm_ram_io_component3 : lpm_ram_dq
165 48 rhoads
         GENERIC MAP (
166
            intended_device_family => "UNUSED",
167
            lpm_width => 8,
168 55 rhoads
            lpm_widthad => ADDRESS_WIDTH-2,
169 48 rhoads
            lpm_indata => "REGISTERED",
170 55 rhoads
            lpm_address_control => "REGISTERED",
171 48 rhoads
            lpm_outdata => "UNREGISTERED",
172
            lpm_file => "code3.hex",
173
            use_eab => "ON",
174
            lpm_type => "LPM_RAM_DQ")
175
         PORT MAP (
176 55 rhoads
            data    => mem_data_w(7 downto 0),
177
            address => mem_address(ADDRESS_WIDTH-1 downto 2),
178
            inclock => clk_inv,
179 48 rhoads
            we      => write_byte_enable(0),
180 55 rhoads
            q       => mem_data_r(7 downto 0));
181
 
182 48 rhoads
   end generate; --altera_ram
183
 
184 2 rhoads
end; --architecture logic
185
 

powered by: WebSVN 2.1.0

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