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

Subversion Repositories plasma

[/] [plasma/] [trunk/] [vhdl/] [mlite_cpu.vhd] - Blame information for rev 432

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 83 rhoads
--    Top level VHDL document that ties the nine other entities together.
14
--
15
-- Executes all MIPS I(tm) opcodes but exceptions and non-aligned
16
-- memory accesses.  Based on information found in:
17 39 rhoads
--    "MIPS RISC Architecture" by Gerry Kane and Joe Heinrich
18
--    and "The Designer's Guide to VHDL" by Peter J. Ashenden
19 83 rhoads
--
20 202 rhoads
-- The CPU is implemented as a two or three stage pipeline.
21 39 rhoads
-- An add instruction would take the following steps (see cpu.gif):
22 202 rhoads
-- Stage #0:
23 83 rhoads
--    1.  The "pc_next" entity passes the program counter (PC) to the 
24
--        "mem_ctrl" entity which fetches the opcode from memory.
25 202 rhoads
-- Stage #1:
26
--    2.  The memory returns the opcode.
27 83 rhoads
-- Stage #2:
28 139 rhoads
--    3.  "Mem_ctrl" passes the opcode to the "control" entity.
29
--    4.  "Control" converts the 32-bit opcode to a 60-bit VLWI opcode
30 39 rhoads
--        and sends control signals to the other entities.
31 139 rhoads
--    5.  Based on the rs_index and rt_index control signals, "reg_bank" 
32 39 rhoads
--        sends the 32-bit reg_source and reg_target to "bus_mux".
33 139 rhoads
--    6.  Based on the a_source and b_source control signals, "bus_mux"
34 39 rhoads
--        multiplexes reg_source onto a_bus and reg_target onto b_bus.
35 202 rhoads
-- Stage #3 (part of stage #2 if using two stage pipeline):
36 139 rhoads
--    7.  Based on the alu_func control signals, "alu" adds the values
37 39 rhoads
--        from a_bus and b_bus and places the result on c_bus.
38 139 rhoads
--    8.  Based on the c_source control signals, "bus_bux" multiplexes
39 39 rhoads
--        c_bus onto reg_dest.
40 139 rhoads
--    9.  Based on the rd_index control signal, "reg_bank" saves
41 39 rhoads
--        reg_dest into the correct register.
42 202 rhoads
-- Stage #3b:
43 139 rhoads
--   10.  Read or write memory if needed.
44 39 rhoads
--
45 139 rhoads
-- All signals are active high. 
46
-- Here are the signals for writing a character to address 0xffff
47 202 rhoads
-- when using a two stage pipeline:
48 39 rhoads
--
49 139 rhoads
-- Program:
50
-- addr     value  opcode 
51
-- =============================
52
--   3c: 00000000  nop
53
--   40: 34040041  li $a0,0x41
54
--   44: 3405ffff  li $a1,0xffff
55
--   48: a0a40000  sb $a0,0($a1)
56
--   4c: 00000000  nop
57
--   50: 00000000  nop
58 83 rhoads
--
59 139 rhoads
--      intr_in                             mem_pause 
60 264 rhoads
--  reset_in                               byte_we     Stages
61
--     ns         address     data_w     data_r        40 44 48 4c 50
62
--   3600  0  0  00000040   00000000   34040041  0  0   1  
63
--   3700  0  0  00000044   00000000   3405FFFF  0  0   2  1  
64
--   3800  0  0  00000048   00000000   A0A40000  0  0      2  1  
65 280 rhoads
--   3900  0  0  0000004C   41414141   00000000  0  0         2  1
66
--   4000  0  0  0000FFFC   41414141   XXXXXX41  1  0         3  2  
67 264 rhoads
--   4100  0  0  00000050   00000000   00000000  0  0               1
68 39 rhoads
---------------------------------------------------------------------
69
library ieee;
70 114 rhoads
use work.mlite_pack.all;
71 39 rhoads
use ieee.std_logic_1164.all;
72 73 rhoads
use ieee.std_logic_unsigned.all;
73 39 rhoads
 
74
entity mlite_cpu is
75 139 rhoads
   generic(memory_type     : string  := "XILINX_16X"; --ALTERA_LPM, or DUAL_PORT_
76 132 rhoads
           mult_type       : string  := "DEFAULT"; --AREA_OPTIMIZED
77
           shifter_type    : string  := "DEFAULT"; --AREA_OPTIMIZED
78
           alu_type        : string  := "DEFAULT"; --AREA_OPTIMIZED
79 202 rhoads
           pipeline_stages : natural := 2); --2 or 3
80 264 rhoads
   port(clk          : in std_logic;
81
        reset_in     : in std_logic;
82
        intr_in      : in std_logic;
83 39 rhoads
 
84 264 rhoads
        address_next : out std_logic_vector(31 downto 2); --for synch ram
85
        byte_we_next : out std_logic_vector(3 downto 0);
86
 
87
        address      : out std_logic_vector(31 downto 2);
88
        byte_we      : out std_logic_vector(3 downto 0);
89
        data_w       : out std_logic_vector(31 downto 0);
90
        data_r       : in std_logic_vector(31 downto 0);
91
        mem_pause    : in std_logic);
92 39 rhoads
end; --entity mlite_cpu
93
 
94
architecture logic of mlite_cpu is
95 202 rhoads
   --When using a two stage pipeline "sigD <= sig".
96
   --When using a three stage pipeline "sigD <= sig when rising_edge(clk)",
97 73 rhoads
   --  so sigD is delayed by one clock cycle.
98 39 rhoads
   signal opcode         : std_logic_vector(31 downto 0);
99 73 rhoads
   signal rs_index       : std_logic_vector(5 downto 0);
100
   signal rt_index       : std_logic_vector(5 downto 0);
101
   signal rd_index       : std_logic_vector(5 downto 0);
102
   signal rd_indexD      : std_logic_vector(5 downto 0);
103
   signal reg_source     : std_logic_vector(31 downto 0);
104
   signal reg_target     : std_logic_vector(31 downto 0);
105
   signal reg_dest       : std_logic_vector(31 downto 0);
106
   signal reg_destD      : std_logic_vector(31 downto 0);
107
   signal a_bus          : std_logic_vector(31 downto 0);
108
   signal a_busD         : std_logic_vector(31 downto 0);
109
   signal b_bus          : std_logic_vector(31 downto 0);
110
   signal b_busD         : std_logic_vector(31 downto 0);
111
   signal c_bus          : std_logic_vector(31 downto 0);
112
   signal c_alu          : std_logic_vector(31 downto 0);
113
   signal c_shift        : std_logic_vector(31 downto 0);
114
   signal c_mult         : std_logic_vector(31 downto 0);
115
   signal c_memory       : std_logic_vector(31 downto 0);
116 39 rhoads
   signal imm            : std_logic_vector(15 downto 0);
117 139 rhoads
   signal pc_future      : std_logic_vector(31 downto 2);
118
   signal pc_current     : std_logic_vector(31 downto 2);
119
   signal pc_plus4       : std_logic_vector(31 downto 2);
120 73 rhoads
   signal alu_func       : alu_function_type;
121
   signal alu_funcD      : alu_function_type;
122
   signal shift_func     : shift_function_type;
123
   signal shift_funcD    : shift_function_type;
124
   signal mult_func      : mult_function_type;
125
   signal mult_funcD     : mult_function_type;
126
   signal branch_func    : branch_function_type;
127 39 rhoads
   signal take_branch    : std_logic;
128
   signal a_source       : a_source_type;
129
   signal b_source       : b_source_type;
130
   signal c_source       : c_source_type;
131
   signal pc_source      : pc_source_type;
132
   signal mem_source     : mem_source_type;
133
   signal pause_mult     : std_logic;
134 73 rhoads
   signal pause_ctrl     : std_logic;
135
   signal pause_pipeline : std_logic;
136
   signal pause_any      : std_logic;
137
   signal pause_non_ctrl : std_logic;
138
   signal pause_bank     : std_logic;
139 39 rhoads
   signal nullify_op     : std_logic;
140
   signal intr_enable    : std_logic;
141
   signal intr_signal    : std_logic;
142 194 rhoads
   signal exception_sig  : std_logic;
143 73 rhoads
   signal reset_reg      : std_logic_vector(3 downto 0);
144 60 rhoads
   signal reset          : std_logic;
145 39 rhoads
begin  --architecture
146
 
147 73 rhoads
   pause_any <= (mem_pause or pause_ctrl) or (pause_mult or pause_pipeline);
148
   pause_non_ctrl <= (mem_pause or pause_mult) or pause_pipeline;
149
   pause_bank <= (mem_pause or pause_ctrl or pause_mult) and not pause_pipeline;
150 128 rhoads
   nullify_op <= '1' when (pc_source = FROM_LBRANCH and take_branch = '0')
151 194 rhoads
                          or intr_signal = '1' or exception_sig = '1'
152 124 rhoads
                          else '0';
153 39 rhoads
   c_bus <= c_alu or c_shift or c_mult;
154 73 rhoads
   reset <= '1' when reset_in = '1' or reset_reg /= "1111" else '0';
155 39 rhoads
 
156 73 rhoads
   --synchronize reset and interrupt pins
157 83 rhoads
   intr_proc: process(clk, reset_in, reset_reg, intr_in, intr_enable,
158 139 rhoads
      pc_source, pc_current, pause_any)
159 73 rhoads
   begin
160
      if reset_in = '1' then
161
         reset_reg <= "0000";
162 124 rhoads
         intr_signal <= '0';
163 73 rhoads
      elsif rising_edge(clk) then
164
         if reset_reg /= "1111" then
165
            reset_reg <= reset_reg + 1;
166
         end if;
167 124 rhoads
 
168 73 rhoads
         --don't try to interrupt a multi-cycle instruction
169 124 rhoads
         if pause_any = '0' then
170 139 rhoads
            if intr_in = '1' and intr_enable = '1' and
171
                  pc_source = FROM_INC4 then
172
               --the epc will contain pc+4
173 124 rhoads
               intr_signal <= '1';
174
            else
175
               intr_signal <= '0';
176
            end if;
177 73 rhoads
         end if;
178 124 rhoads
 
179 73 rhoads
      end if;
180
   end process;
181 39 rhoads
 
182
   u1_pc_next: pc_next PORT MAP (
183
        clk          => clk,
184 60 rhoads
        reset_in     => reset,
185 96 rhoads
        take_branch  => take_branch,
186 73 rhoads
        pause_in     => pause_any,
187
        pc_new       => c_bus(31 downto 2),
188 39 rhoads
        opcode25_0   => opcode(25 downto 0),
189
        pc_source    => pc_source,
190 139 rhoads
        pc_future    => pc_future,
191
        pc_current   => pc_current,
192
        pc_plus4     => pc_plus4);
193 39 rhoads
 
194 73 rhoads
   u2_mem_ctrl: mem_ctrl
195
      PORT MAP (
196 39 rhoads
        clk          => clk,
197 60 rhoads
        reset_in     => reset,
198 73 rhoads
        pause_in     => pause_non_ctrl,
199 39 rhoads
        nullify_op   => nullify_op,
200 139 rhoads
        address_pc   => pc_future,
201 39 rhoads
        opcode_out   => opcode,
202
 
203 139 rhoads
        address_in   => c_bus,
204 39 rhoads
        mem_source   => mem_source,
205
        data_write   => reg_target,
206
        data_read    => c_memory,
207 73 rhoads
        pause_out    => pause_ctrl,
208 39 rhoads
 
209 264 rhoads
        address_next => address_next,
210
        byte_we_next => byte_we_next,
211 39 rhoads
 
212 264 rhoads
        address      => address,
213
        byte_we      => byte_we,
214
        data_w       => data_w,
215
        data_r       => data_r);
216
 
217 39 rhoads
   u3_control: control PORT MAP (
218
        opcode       => opcode,
219
        intr_signal  => intr_signal,
220
        rs_index     => rs_index,
221
        rt_index     => rt_index,
222
        rd_index     => rd_index,
223
        imm_out      => imm,
224 73 rhoads
        alu_func     => alu_func,
225
        shift_func   => shift_func,
226
        mult_func    => mult_func,
227
        branch_func  => branch_func,
228 39 rhoads
        a_source_out => a_source,
229
        b_source_out => b_source,
230
        c_source_out => c_source,
231
        pc_source_out=> pc_source,
232 194 rhoads
        mem_source_out=> mem_source,
233
        exception_out=> exception_sig);
234 39 rhoads
 
235 47 rhoads
   u4_reg_bank: reg_bank
236
      generic map(memory_type => memory_type)
237
      port map (
238 39 rhoads
        clk            => clk,
239 60 rhoads
        reset_in       => reset,
240 73 rhoads
        pause          => pause_bank,
241 39 rhoads
        rs_index       => rs_index,
242
        rt_index       => rt_index,
243 73 rhoads
        rd_index       => rd_indexD,
244 39 rhoads
        reg_source_out => reg_source,
245
        reg_target_out => reg_target,
246 73 rhoads
        reg_dest_new   => reg_destD,
247 39 rhoads
        intr_enable    => intr_enable);
248
 
249
   u5_bus_mux: bus_mux port map (
250
        imm_in       => imm,
251
        reg_source   => reg_source,
252
        a_mux        => a_source,
253
        a_out        => a_bus,
254
 
255
        reg_target   => reg_target,
256
        b_mux        => b_source,
257
        b_out        => b_bus,
258
 
259
        c_bus        => c_bus,
260
        c_memory     => c_memory,
261 139 rhoads
        c_pc         => pc_current,
262 39 rhoads
        c_pc_plus4   => pc_plus4,
263
        c_mux        => c_source,
264
        reg_dest_out => reg_dest,
265
 
266 73 rhoads
        branch_func  => branch_func,
267 39 rhoads
        take_branch  => take_branch);
268
 
269 47 rhoads
   u6_alu: alu
270 139 rhoads
      generic map (alu_type => alu_type)
271 47 rhoads
      port map (
272 73 rhoads
        a_in         => a_busD,
273
        b_in         => b_busD,
274
        alu_function => alu_funcD,
275 39 rhoads
        c_alu        => c_alu);
276
 
277 114 rhoads
   u7_shifter: shifter
278
      generic map (shifter_type => shifter_type)
279
      port map (
280 73 rhoads
        value        => b_busD,
281
        shift_amount => a_busD(4 downto 0),
282
        shift_func   => shift_funcD,
283 39 rhoads
        c_shift      => c_shift);
284
 
285 47 rhoads
   u8_mult: mult
286 139 rhoads
      generic map (mult_type => mult_type)
287 47 rhoads
      port map (
288 39 rhoads
        clk       => clk,
289 128 rhoads
        reset_in  => reset,
290 73 rhoads
        a         => a_busD,
291
        b         => b_busD,
292
        mult_func => mult_funcD,
293 39 rhoads
        c_mult    => c_mult,
294
        pause_out => pause_mult);
295
 
296 202 rhoads
   pipeline2: if pipeline_stages <= 2 generate
297 73 rhoads
      a_busD <= a_bus;
298
      b_busD <= b_bus;
299
      alu_funcD <= alu_func;
300
      shift_funcD <= shift_func;
301
      mult_funcD <= mult_func;
302
      rd_indexD <= rd_index;
303
      reg_destD <= reg_dest;
304
      pause_pipeline <= '0';
305
   end generate; --pipeline2
306
 
307 202 rhoads
   pipeline3: if pipeline_stages > 2 generate
308
      --When operating in three stage pipeline mode, the following signals
309 73 rhoads
      --are delayed by one clock cycle:  a_bus, b_bus, alu/shift/mult_func,
310
      --c_source, and rd_index.
311
   u9_pipeline: pipeline port map (
312
        clk            => clk,
313
        reset          => reset,
314
        a_bus          => a_bus,
315
        a_busD         => a_busD,
316
        b_bus          => b_bus,
317
        b_busD         => b_busD,
318
        alu_func       => alu_func,
319
        alu_funcD      => alu_funcD,
320
        shift_func     => shift_func,
321
        shift_funcD    => shift_funcD,
322
        mult_func      => mult_func,
323
        mult_funcD     => mult_funcD,
324
        reg_dest       => reg_dest,
325
        reg_destD      => reg_destD,
326
        rd_index       => rd_index,
327
        rd_indexD      => rd_indexD,
328
 
329
        rs_index       => rs_index,
330
        rt_index       => rt_index,
331
        pc_source      => pc_source,
332
        mem_source     => mem_source,
333
        a_source       => a_source,
334
        b_source       => b_source,
335
        c_source       => c_source,
336
        c_bus          => c_bus,
337
        pause_any      => pause_any,
338
        pause_pipeline => pause_pipeline);
339
 
340 202 rhoads
   end generate; --pipeline3
341 139 rhoads
 
342 39 rhoads
end; --architecture logic

powered by: WebSVN 2.1.0

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