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

Subversion Repositories neo430

[/] [neo430/] [trunk/] [neo430/] [rtl/] [core/] [neo430_reg_file.vhd] - Blame information for rev 198

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 198 zero_gravi
-- #################################################################################################
2
-- #  << NEO430 - CPU Register File >>                                                             #
3
-- # ********************************************************************************************* #
4
-- # General data registers, program counter, status register and constant generator.              #
5
-- # ********************************************************************************************* #
6
-- # BSD 3-Clause License                                                                          #
7
-- #                                                                                               #
8
-- # Copyright (c) 2020, Stephan Nolting. All rights reserved.                                     #
9
-- #                                                                                               #
10
-- # Redistribution and use in source and binary forms, with or without modification, are          #
11
-- # permitted provided that the following conditions are met:                                     #
12
-- #                                                                                               #
13
-- # 1. Redistributions of source code must retain the above copyright notice, this list of        #
14
-- #    conditions and the following disclaimer.                                                   #
15
-- #                                                                                               #
16
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
17
-- #    conditions and the following disclaimer in the documentation and/or other materials        #
18
-- #    provided with the distribution.                                                            #
19
-- #                                                                                               #
20
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
21
-- #    endorse or promote products derived from this software without specific prior written      #
22
-- #    permission.                                                                                #
23
-- #                                                                                               #
24
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
25
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
26
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
27
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
28
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
29
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
30
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
31
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
32
-- # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
33
-- # ********************************************************************************************* #
34
-- # The NEO430 Processor - https://github.com/stnolting/neo430                                    #
35
-- #################################################################################################
36
 
37
library ieee;
38
use ieee.std_logic_1164.all;
39
use ieee.numeric_std.all;
40
 
41
library neo430;
42
use neo430.neo430_package.all;
43
 
44
entity neo430_reg_file is
45
  generic (
46
    BOOTLD_USE  : boolean := true; -- implement and use bootloader?
47
    IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory?
48
  );
49
  port (
50
    -- global control --
51
    clk_i  : in  std_ulogic; -- global clock, rising edge
52
    rst_i  : in  std_ulogic; -- global reset, low-active, async
53
    -- data input --
54
    alu_i  : in  std_ulogic_vector(15 downto 0); -- data from alu
55
    addr_i : in  std_ulogic_vector(15 downto 0); -- data from addr unit
56
    flag_i : in  std_ulogic_vector(04 downto 0); -- new ALU flags
57
    -- control --
58
    ctrl_i : in  std_ulogic_vector(ctrl_width_c-1 downto 0);
59
    -- data output --
60
    data_o : out std_ulogic_vector(15 downto 0); -- read data
61
    sreg_o : out std_ulogic_vector(15 downto 0)  -- current SR
62
  );
63
end neo430_reg_file;
64
 
65
architecture neo430_reg_file_rtl of neo430_reg_file is
66
 
67
  -- boot address for PC --
68
  -- boot from beginning of boot ROM (boot_base_c) if bootloader is used, otherwise boot from beginning of IMEM (imem_base_c)
69
  -- By not using a reset-like init of the PC, the whole register file (except for SR and CG)
70
  -- can be mapped to distributed RAM saving logic resources
71
  constant pc_boot_addr_c : std_ulogic_vector(15 downto 0) := cond_sel_stdulogicvector_f(BOOTLD_USE, boot_base_c, imem_base_c);
72
 
73
  -- register file (including dummy regs) --
74
  type   reg_file_t is array (15 downto 0) of std_ulogic_vector(15 downto 0);
75
  signal reg_file : reg_file_t;
76
  signal sreg     : std_ulogic_vector(15 downto 0);
77
  signal sreg_int : std_ulogic_vector(15 downto 0);
78
 
79
  --- RAM attribute to inhibit bypass-logic - Altera only! ---
80
  attribute ramstyle : string;
81
  attribute ramstyle of reg_file : signal is "no_rw_check";
82
 
83
  -- misc --
84
  signal in_data : std_ulogic_vector(15 downto 0); -- input selection
85
 
86
begin
87
 
88
  -- Input Operand Selection --------------------------------------------------
89
  -- -----------------------------------------------------------------------------
90
  in_data <= pc_boot_addr_c when (ctrl_i(ctrl_rf_boot_c)   = '1') else
91
             addr_i         when (ctrl_i(ctrl_rf_in_sel_c) = '1') else alu_i;
92
 
93
 
94
  -- Register File Write Access -----------------------------------------------
95
  -- -----------------------------------------------------------------------------
96
  sreg_write: process(rst_i, clk_i)
97
  begin
98
    if (rst_i = '0') then
99
      sreg <= (others => '0'); -- here we NEED a true hardware reset
100
    elsif rising_edge(clk_i) then
101
      -- physical status register --
102
      if ((ctrl_i(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) = reg_sr_c) and (ctrl_i(ctrl_rf_wb_en_c) = '1')) then -- valid SREG write
103
        sreg(sreg_c_c) <= in_data(sreg_c_c);
104
        sreg(sreg_z_c) <= in_data(sreg_z_c);
105
        sreg(sreg_n_c) <= in_data(sreg_n_c);
106
        sreg(sreg_i_c) <= in_data(sreg_i_c);
107
        sreg(sreg_s_c) <= in_data(sreg_s_c);
108
        sreg(sreg_v_c) <= in_data(sreg_v_c);
109
        sreg(sreg_q_c) <= in_data(sreg_q_c);
110
        if (use_xalu_c = true) then -- implement parity computation?
111
          sreg(sreg_p_c) <= in_data(sreg_p_c);
112
        end if;
113
        if (IMEM_AS_ROM = false) then -- r-flag is 0 when IMEM is ROM
114
          sreg(sreg_r_c) <= in_data(sreg_r_c);
115
        end if;
116
      else -- automatic update
117
        sreg(sreg_q_c) <= '0'; -- auto-clear
118
        -- disable sleep mode --
119
        if (ctrl_i(ctrl_rf_dsleep_c) = '1') then
120
          sreg(sreg_s_c) <= '0';
121
        end if;
122
        -- disable interrupt enable --
123
        if (ctrl_i(ctrl_rf_dgie_c) = '1') then
124
          sreg(sreg_i_c) <= '0';
125
        end if;
126
         -- update ALU flags --
127
        if (ctrl_i(ctrl_rf_fup_c) = '1') then
128
          sreg(sreg_c_c) <= flag_i(flag_c_c);
129
          sreg(sreg_z_c) <= flag_i(flag_z_c);
130
          sreg(sreg_n_c) <= flag_i(flag_n_c);
131
          sreg(sreg_v_c) <= flag_i(flag_v_c);
132
          if (use_xalu_c = true) then -- implement parity computation?
133
            sreg(sreg_p_c) <= flag_i(flag_p_c);
134
          end if;
135
        end if;
136
      end if;
137
    end if;
138
  end process sreg_write;
139
 
140
  -- construct logical status register --
141
  sreg_combine: process(sreg)
142
  begin
143
    -- SREG for system --
144
    sreg_o <= (others => '0');
145
    sreg_o(sreg_c_c) <= sreg(sreg_c_c);
146
    sreg_o(sreg_z_c) <= sreg(sreg_z_c);
147
    sreg_o(sreg_n_c) <= sreg(sreg_n_c);
148
    sreg_o(sreg_i_c) <= sreg(sreg_i_c);
149
    sreg_o(sreg_s_c) <= sreg(sreg_s_c);
150
    sreg_o(sreg_v_c) <= sreg(sreg_v_c);
151
    sreg_o(sreg_q_c) <= sreg(sreg_q_c);
152
    sreg_o(sreg_r_c) <= sreg(sreg_r_c);
153
    if (use_xalu_c = true) then -- implement parity computation?
154
      sreg_o(sreg_p_c) <= sreg(sreg_p_c);
155
    end if;
156
    -- SREG for user --
157
    sreg_int <= (others => '0');
158
    sreg_int(sreg_c_c) <= sreg(sreg_c_c);
159
    sreg_int(sreg_z_c) <= sreg(sreg_z_c);
160
    sreg_int(sreg_n_c) <= sreg(sreg_n_c);
161
    sreg_int(sreg_i_c) <= sreg(sreg_i_c);
162
    sreg_int(sreg_s_c) <= sreg(sreg_s_c);
163
    sreg_int(sreg_v_c) <= sreg(sreg_v_c);
164
  --sreg_int(sreg_q_c) <= sreg(sreg_q_c); -- is always zero for user
165
    sreg_int(sreg_r_c) <= sreg(sreg_r_c);
166
    if (use_xalu_c = true) then -- implement parity computation?
167
      sreg_int(sreg_p_c) <= sreg(sreg_p_c);
168
    end if;
169
  end process sreg_combine;
170
 
171
  -- general purpose register file (including PC, SP, dummy SR and dummy CG) --
172
  rf_write: process(clk_i)
173
  begin
174
    if rising_edge(clk_i) then
175
      if (ctrl_i(ctrl_rf_wb_en_c) = '1') then -- valid register file write
176
        reg_file(to_integer(unsigned(ctrl_i(ctrl_rf_adr3_c downto ctrl_rf_adr0_c)))) <= in_data;
177
      end if;
178
    end if;
179
  end process rf_write;
180
 
181
 
182
  -- Register File Read Access ------------------------------------------------
183
  -- -----------------------------------------------------------------------------
184
  rf_read: process(ctrl_i, reg_file, sreg_int)
185
    variable const_sel_v : std_ulogic_vector(2 downto 0);
186
  begin
187
    if ((ctrl_i(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) = reg_sr_c) or
188
        (ctrl_i(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) = reg_cg_c)) then
189
      -- constant generator / SR read access --
190
      const_sel_v := ctrl_i(ctrl_rf_adr0_c) & ctrl_i(ctrl_rf_as1_c) & ctrl_i(ctrl_rf_as0_c);
191
      case const_sel_v is
192
        when "000"  => data_o <= sreg_int; -- read SR
193
        when "001"  => data_o <= x"0000"; -- absolute addressing mode
194
        when "010"  => data_o <= x"0004"; -- +4
195
        when "011"  => data_o <= x"0008"; -- +8
196
        when "100"  => data_o <= x"0000"; --  0
197
        when "101"  => data_o <= x"0001"; -- +1
198
        when "110"  => data_o <= x"0002"; -- +2
199
        when "111"  => data_o <= x"FFFF"; -- -1
200
        when others => data_o <= (others => '-');
201
      end case;
202
    else -- gp register file read access
203
      data_o <= reg_file(to_integer(unsigned(ctrl_i(ctrl_rf_adr3_c downto ctrl_rf_adr0_c))));
204
    end if;
205
  end process rf_read;
206
 
207
 
208
end neo430_reg_file_rtl;

powered by: WebSVN 2.1.0

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