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

Subversion Repositories mlite

[/] [mlite/] [trunk/] [vhdl/] [mlite_cpu.vhd] - Blame information for rev 73

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

Line No. Rev Author Line
1 39 rhoads
---------------------------------------------------------------------
2 43 rhoads
-- TITLE: Plasma CPU core
3 39 rhoads
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4
-- DATE CREATED: 2/15/01
5
-- FILENAME: mlite_cpu.vhd
6 43 rhoads
-- PROJECT: Plasma CPU core
7 39 rhoads
-- COPYRIGHT: Software placed into the public domain by the author.
8
--    Software 'as is' without warranty.  Author liable for nothing.
9
-- NOTE:  MIPS(tm) and MIPS I(tm) are registered trademarks of MIPS 
10
--    Technologies.  MIPS Technologies does not endorse and is not 
11
--    associated with this project.
12
-- DESCRIPTION:
13
-- Top level VHDL document that ties the eight other entities together.
14 43 rhoads
-- Executes most MIPS I(tm) opcodes.  Based on information found in:
15 39 rhoads
--    "MIPS RISC Architecture" by Gerry Kane and Joe Heinrich
16
--    and "The Designer's Guide to VHDL" by Peter J. Ashenden
17
-- An add instruction would take the following steps (see cpu.gif):
18
--    1.  The "pc_next" entity would have previously passed the program
19
--        counter (PC) to the "mem_ctrl" entity.
20
--    2.  "Mem_ctrl" passes the opcode to the "control" entity.
21
--    3.  "Control" converts the 32-bit opcode to a 60-bit VLWI opcode
22
--        and sends control signals to the other entities.
23
--    4.  Based on the rs_index and rt_index control signals, "reg_bank" 
24
--        sends the 32-bit reg_source and reg_target to "bus_mux".
25
--    5.  Based on the a_source and b_source control signals, "bus_mux"
26
--        multiplexes reg_source onto a_bus and reg_target onto b_bus.
27
--    6.  Based on the alu_func control signals, "alu" adds the values
28
--        from a_bus and b_bus and places the result on c_bus.
29
--    7.  Based on the c_source control signals, "bus_bux" multiplexes
30
--        c_bus onto reg_dest.
31
--    8.  Based on the rd_index control signal, "reg_bank" saves
32
--        reg_dest into the correct register.
33 73 rhoads
-- The CPU is implemented as a two/three stage pipeline with step #1 in 
34
-- the first stage and steps #2-#8 occuring the second stage.  When 
35
-- operating with a three stage pipeline, steps #6-#8 occur in the 
36
-- third stage.
37 39 rhoads
--
38 73 rhoads
-- Writing to high memory where a(31)='1' takes four cycles to meet RAM 
39
-- address hold times.
40
-- Addresses with a(31)='0' are assumed to be clocked and take two cycles.
41 39 rhoads
-- Here are the signals for writing a character to address 0xffff:
42
--
43
--      mem_write                           
44
--    interrupt                     mem_byte_sel
45
--      reset                        mem_pause  
46
--       ns    mem_address m_data_w m_data_r    
47
--   ===========================================
48
--     6700 0 0 0 000002A4 ZZZZZZZZ A0AE0000 0 0  (  fetch write opcode)
49
--     6800 0 0 0 000002B0 ZZZZZZZZ 0443FFF6 0 0  (1 fetch NEXT opcode)
50 73 rhoads
--     6900 0 0 1 0000FFFF 31313131 ZZZZZZZZ 0 1  (2 write the low byte)
51
--     7000 0 0 0 000002B4 ZZZZZZZZ 00441806 0 0  (  execute NEXT opcode)
52 39 rhoads
---------------------------------------------------------------------
53
library ieee;
54
use ieee.std_logic_1164.all;
55 73 rhoads
use ieee.std_logic_unsigned.all;
56 39 rhoads
use work.mlite_pack.all;
57
 
58
entity mlite_cpu is
59 73 rhoads
   generic(memory_type     : string  := "ALTERA";
60
           pipeline_stages : natural := 3;
61
           accurate_timing : boolean := false);
62 39 rhoads
   port(clk         : in std_logic;
63
        reset_in    : in std_logic;
64
        intr_in     : in std_logic;
65
 
66
        mem_address : out std_logic_vector(31 downto 0);
67
        mem_data_w  : out std_logic_vector(31 downto 0);
68
        mem_data_r  : in std_logic_vector(31 downto 0);
69
        mem_byte_sel: out std_logic_vector(3 downto 0);
70
        mem_write   : out std_logic;
71
        mem_pause   : in std_logic);
72
end; --entity mlite_cpu
73
 
74
architecture logic of mlite_cpu is
75 73 rhoads
   --When using a two stage pipeline "sigD <= sig".
76
   --When using a three stage pipeline "sigD <= sig when rising_edge(clk)",
77
   --  so sigD is delayed by one clock cycle.
78 39 rhoads
   signal opcode         : std_logic_vector(31 downto 0);
79 73 rhoads
   signal rs_index       : std_logic_vector(5 downto 0);
80
   signal rt_index       : std_logic_vector(5 downto 0);
81
   signal rd_index       : std_logic_vector(5 downto 0);
82
   signal rd_indexD      : std_logic_vector(5 downto 0);
83
   signal reg_source     : std_logic_vector(31 downto 0);
84
   signal reg_target     : std_logic_vector(31 downto 0);
85
   signal reg_dest       : std_logic_vector(31 downto 0);
86
   signal reg_destD      : std_logic_vector(31 downto 0);
87
   signal a_bus          : std_logic_vector(31 downto 0);
88
   signal a_busD         : std_logic_vector(31 downto 0);
89
   signal b_bus          : std_logic_vector(31 downto 0);
90
   signal b_busD         : std_logic_vector(31 downto 0);
91
   signal c_bus          : std_logic_vector(31 downto 0);
92
   signal c_alu          : std_logic_vector(31 downto 0);
93
   signal c_shift        : std_logic_vector(31 downto 0);
94
   signal c_mult         : std_logic_vector(31 downto 0);
95
   signal c_memory       : std_logic_vector(31 downto 0);
96 39 rhoads
   signal imm            : std_logic_vector(15 downto 0);
97
   signal pc             : std_logic_vector(31 downto 0);
98
   signal pc_plus4       : std_logic_vector(31 downto 0);
99 73 rhoads
   signal alu_func       : alu_function_type;
100
   signal alu_funcD      : alu_function_type;
101
   signal shift_func     : shift_function_type;
102
   signal shift_funcD    : shift_function_type;
103
   signal mult_func      : mult_function_type;
104
   signal mult_funcD     : mult_function_type;
105
   signal branch_func    : branch_function_type;
106 39 rhoads
   signal take_branch    : std_logic;
107 73 rhoads
   signal take_branchD   : std_logic;
108 39 rhoads
   signal a_source       : a_source_type;
109
   signal b_source       : b_source_type;
110
   signal c_source       : c_source_type;
111
   signal pc_source      : pc_source_type;
112
   signal mem_source     : mem_source_type;
113
   signal pause_mult     : std_logic;
114 73 rhoads
   signal pause_ctrl     : std_logic;
115
   signal pause_pipeline : std_logic;
116
   signal pause_any      : std_logic;
117
   signal pause_non_ctrl : std_logic;
118
   signal pause_bank     : std_logic;
119 39 rhoads
   signal nullify_op     : std_logic;
120
   signal intr_enable    : std_logic;
121
   signal intr_signal    : std_logic;
122 73 rhoads
   signal reset_reg      : std_logic_vector(3 downto 0);
123 60 rhoads
   signal reset          : std_logic;
124 39 rhoads
begin  --architecture
125
 
126 73 rhoads
   pause_any <= (mem_pause or pause_ctrl) or (pause_mult or pause_pipeline);
127
   pause_non_ctrl <= (mem_pause or pause_mult) or pause_pipeline;
128
   pause_bank <= (mem_pause or pause_ctrl or pause_mult) and not pause_pipeline;
129 39 rhoads
   nullify_op <= '1' when pc_source = from_lbranch and
130 73 rhoads
                     (take_branchD = '0' or branch_func = branch_yes) else
131 39 rhoads
                 '0';
132
   c_bus <= c_alu or c_shift or c_mult;
133 73 rhoads
   reset <= '1' when reset_in = '1' or reset_reg /= "1111" else '0';
134 39 rhoads
 
135 73 rhoads
   --synchronize reset and interrupt pins
136
   intr_proc: process(clk, reset_in, intr_in, intr_enable, pc_source, pc, pause_any)
137
   begin
138
      if reset_in = '1' then
139
         reset_reg <= "0000";
140
      elsif rising_edge(clk) then
141
         if reset_reg /= "1111" then
142
            reset_reg <= reset_reg + 1;
143
         end if;
144 39 rhoads
      end if;
145 73 rhoads
      if rising_edge(clk) then
146
         --don't try to interrupt a multi-cycle instruction
147
         if intr_in = '1' and intr_enable = '1' and
148
               pc_source = from_inc4 and pc(2) = '0' and
149
               pause_any = '0' then
150
            --the epc will be backed up one opcode (pc-4)
151
            intr_signal <= '1';
152
         else
153
            intr_signal <= '0';
154
         end if;
155
      end if;
156
   end process;
157 39 rhoads
 
158
   u1_pc_next: pc_next PORT MAP (
159
        clk          => clk,
160 60 rhoads
        reset_in     => reset,
161 73 rhoads
        take_branch  => take_branchD,
162
        pause_in     => pause_any,
163
        pc_new       => c_bus(31 downto 2),
164 39 rhoads
        opcode25_0   => opcode(25 downto 0),
165
        pc_source    => pc_source,
166
        pc_out       => pc,
167
        pc_out_plus4 => pc_plus4);
168
 
169 73 rhoads
   u2_mem_ctrl: mem_ctrl
170
      generic map (ACCURATE_TIMING => accurate_timing)
171
      PORT MAP (
172 39 rhoads
        clk          => clk,
173 60 rhoads
        reset_in     => reset,
174 73 rhoads
        pause_in     => pause_non_ctrl,
175 39 rhoads
        nullify_op   => nullify_op,
176
        address_pc   => pc,
177
        opcode_out   => opcode,
178
 
179 73 rhoads
        address_data => c_bus,
180 39 rhoads
        mem_source   => mem_source,
181
        data_write   => reg_target,
182
        data_read    => c_memory,
183 73 rhoads
        pause_out    => pause_ctrl,
184 39 rhoads
 
185
        mem_address  => mem_address,
186
        mem_data_w   => mem_data_w,
187
        mem_data_r   => mem_data_r,
188
        mem_byte_sel => mem_byte_sel,
189 73 rhoads
        mem_write    => mem_write);
190 39 rhoads
 
191
   u3_control: control PORT MAP (
192
        opcode       => opcode,
193
        intr_signal  => intr_signal,
194
        rs_index     => rs_index,
195
        rt_index     => rt_index,
196
        rd_index     => rd_index,
197
        imm_out      => imm,
198 73 rhoads
        alu_func     => alu_func,
199
        shift_func   => shift_func,
200
        mult_func    => mult_func,
201
        branch_func  => branch_func,
202 39 rhoads
        a_source_out => a_source,
203
        b_source_out => b_source,
204
        c_source_out => c_source,
205
        pc_source_out=> pc_source,
206
        mem_source_out=> mem_source);
207
 
208 47 rhoads
   u4_reg_bank: reg_bank
209
      generic map(memory_type => memory_type)
210
      port map (
211 39 rhoads
        clk            => clk,
212 60 rhoads
        reset_in       => reset,
213 73 rhoads
        pause          => pause_bank,
214 39 rhoads
        rs_index       => rs_index,
215
        rt_index       => rt_index,
216 73 rhoads
        rd_index       => rd_indexD,
217 39 rhoads
        reg_source_out => reg_source,
218
        reg_target_out => reg_target,
219 73 rhoads
        reg_dest_new   => reg_destD,
220 39 rhoads
        intr_enable    => intr_enable);
221
 
222
   u5_bus_mux: bus_mux port map (
223
        imm_in       => imm,
224
        reg_source   => reg_source,
225
        a_mux        => a_source,
226
        a_out        => a_bus,
227
 
228
        reg_target   => reg_target,
229
        b_mux        => b_source,
230
        b_out        => b_bus,
231
 
232
        c_bus        => c_bus,
233
        c_memory     => c_memory,
234
        c_pc         => pc,
235
        c_pc_plus4   => pc_plus4,
236
        c_mux        => c_source,
237
        reg_dest_out => reg_dest,
238
 
239 73 rhoads
        branch_func  => branch_func,
240 39 rhoads
        take_branch  => take_branch);
241
 
242 47 rhoads
   u6_alu: alu
243
      generic map (adder_type => memory_type)
244
      port map (
245 73 rhoads
        a_in         => a_busD,
246
        b_in         => b_busD,
247
        alu_function => alu_funcD,
248 39 rhoads
        c_alu        => c_alu);
249
 
250
   u7_shifter: shifter port map (
251 73 rhoads
        value        => b_busD,
252
        shift_amount => a_busD(4 downto 0),
253
        shift_func   => shift_funcD,
254 39 rhoads
        c_shift      => c_shift);
255
 
256 47 rhoads
   u8_mult: mult
257
      generic map (adder_type => memory_type)
258
      port map (
259 39 rhoads
        clk       => clk,
260 73 rhoads
        a         => a_busD,
261
        b         => b_busD,
262
        mult_func => mult_funcD,
263 39 rhoads
        c_mult    => c_mult,
264
        pause_out => pause_mult);
265
 
266 73 rhoads
   pipeline2: if pipeline_stages <= 2 generate
267
      a_busD <= a_bus;
268
      b_busD <= b_bus;
269
      alu_funcD <= alu_func;
270
      shift_funcD <= shift_func;
271
      mult_funcD <= mult_func;
272
      rd_indexD <= rd_index;
273
 
274
      reg_destD <= reg_dest;
275
      take_branchD <= take_branch;
276
      pause_pipeline <= '0';
277
   end generate; --pipeline2
278
 
279
   pipeline3: if pipeline_stages >= 3 generate
280
      --When operating in three stage pipeline mode, the following signals
281
      --are delayed by one clock cycle:  a_bus, b_bus, alu/shift/mult_func,
282
      --c_source, and rd_index.
283
   u9_pipeline: pipeline port map (
284
        clk            => clk,
285
        reset          => reset,
286
        a_bus          => a_bus,
287
        a_busD         => a_busD,
288
        b_bus          => b_bus,
289
        b_busD         => b_busD,
290
        alu_func       => alu_func,
291
        alu_funcD      => alu_funcD,
292
        shift_func     => shift_func,
293
        shift_funcD    => shift_funcD,
294
        mult_func      => mult_func,
295
        mult_funcD     => mult_funcD,
296
        reg_dest       => reg_dest,
297
        reg_destD      => reg_destD,
298
        rd_index       => rd_index,
299
        rd_indexD      => rd_indexD,
300
 
301
        rs_index       => rs_index,
302
        rt_index       => rt_index,
303
        pc_source      => pc_source,
304
        mem_source     => mem_source,
305
        a_source       => a_source,
306
        b_source       => b_source,
307
        c_source       => c_source,
308
        c_bus          => c_bus,
309
        take_branch    => take_branch,
310
        take_branchD   => take_branchD,
311
        pause_any      => pause_any,
312
        pause_pipeline => pause_pipeline);
313
   end generate; --pipeline3
314
 
315 39 rhoads
end; --architecture logic
316
 

powered by: WebSVN 2.1.0

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