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

Subversion Repositories plasma

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

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
-- 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 83 rhoads
-- Stage #1:
23
--    1.  The "pc_next" entity passes the program counter (PC) to the 
24
--        "mem_ctrl" entity which fetches the opcode from memory.
25
-- Stage #2:
26 39 rhoads
--    2.  "Mem_ctrl" passes the opcode to the "control" entity.
27
--    3.  "Control" converts the 32-bit opcode to a 60-bit VLWI opcode
28
--        and sends control signals to the other entities.
29
--    4.  Based on the rs_index and rt_index control signals, "reg_bank" 
30
--        sends the 32-bit reg_source and reg_target to "bus_mux".
31
--    5.  Based on the a_source and b_source control signals, "bus_mux"
32
--        multiplexes reg_source onto a_bus and reg_target onto b_bus.
33 83 rhoads
-- Stage #3:
34 39 rhoads
--    6.  Based on the alu_func control signals, "alu" adds the values
35
--        from a_bus and b_bus and places the result on c_bus.
36
--    7.  Based on the c_source control signals, "bus_bux" multiplexes
37
--        c_bus onto reg_dest.
38
--    8.  Based on the rd_index control signal, "reg_bank" saves
39
--        reg_dest into the correct register.
40
--
41 83 rhoads
-- All signals are active high.  Writing to high memory where a(31)='1' 
42
-- takes five cycles to meet RAM address hold times.
43
-- Addresses with a(31)='0' are assumed to be clocked and take three cycles.
44 39 rhoads
-- Here are the signals for writing a character to address 0xffff:
45
--
46 83 rhoads
--      intr_in                        mem_pause    
47
--   reset_in                        mem_write      
48
--      clk                     mem_byte_sel        
49
--     ns    mem_address m_data_r m_data_w 
50
-- =============================================
51
--   3000 1 0 0 0000002C A2820000 ZZZZZZZZ 0 0 0  (0 fetch write opcode)
52
--   3050 0 0 0 0000002C A2820000 ZZZZZZZZ 0 0 0
53
--   3100 1 0 0 00000030 340A0041 ZZZZZZZZ 0 0 0  (1 execute write opcode)
54
--   3150 0 0 0 00000030 340A0041 ZZZZZZZZ 0 0 0
55
--   3200 1 0 0 00000030 340A0041 ZZZZZZZZ 0 0 0  (2 calculating address)
56
--   3250 0 0 0 00000030 340A0041 ZZZZZZZZ 0 0 0
57
--   3300 1 0 0 0000FFFF ZZZZZZZZ 6A6A6A6A 1 1 0  (3 writing value)
58
--   3350 0 0 0 0000FFFF ZZZZZZZZ 6A6A6A6A 1 1 0
59
--   3400 1 0 0 00000034 340B0042 ZZZZZZZZ 0 0 0
60
--   3450 0 0 0 00000034 340B0042 ZZZZZZZZ 0 0 0
61
--
62
-- Program:
63
-- addr     value  opcode   args
64
-- ===================================
65
-- 002c  a2820000      sb   $v0,0($s4)
66
-- 0030  340a0041      li   $t2,0x41
67
-- 0034  340b0042      li   $t3,0x42
68 39 rhoads
---------------------------------------------------------------------
69
library ieee;
70 114 rhoads
use work.mlite_pack.all;
71
--library ieee, mlite_lib;
72
--use mlite_lib.mlite_pack.all;
73 39 rhoads
use ieee.std_logic_1164.all;
74 73 rhoads
use ieee.std_logic_unsigned.all;
75 39 rhoads
 
76
entity mlite_cpu is
77 114 rhoads
   generic(memory_type     : string  := "DUAL_PORT_XILINX_XC4000XLA";
78
           adder_type      : string  := "GENERIC";
79
           mult_type       : string  := "AREA_OPTIMIZED";
80
           shifter_type    : string  := "GENERIC";
81
           alu_type        : string  := "GENERIC";
82 73 rhoads
           pipeline_stages : natural := 3;
83 83 rhoads
           accurate_timing : boolean := true);
84 39 rhoads
   port(clk         : in std_logic;
85
        reset_in    : in std_logic;
86
        intr_in     : in std_logic;
87
 
88
        mem_address : out std_logic_vector(31 downto 0);
89
        mem_data_w  : out std_logic_vector(31 downto 0);
90
        mem_data_r  : in std_logic_vector(31 downto 0);
91
        mem_byte_sel: out std_logic_vector(3 downto 0);
92
        mem_write   : out std_logic;
93
        mem_pause   : in std_logic);
94
end; --entity mlite_cpu
95
 
96
architecture logic of mlite_cpu is
97 73 rhoads
   --When using a two stage pipeline "sigD <= sig".
98
   --When using a three stage pipeline "sigD <= sig when rising_edge(clk)",
99
   --  so sigD is delayed by one clock cycle.
100 39 rhoads
   signal opcode         : std_logic_vector(31 downto 0);
101 73 rhoads
   signal rs_index       : std_logic_vector(5 downto 0);
102
   signal rt_index       : std_logic_vector(5 downto 0);
103
   signal rd_index       : std_logic_vector(5 downto 0);
104
   signal rd_indexD      : std_logic_vector(5 downto 0);
105
   signal reg_source     : std_logic_vector(31 downto 0);
106
   signal reg_target     : std_logic_vector(31 downto 0);
107
   signal reg_dest       : std_logic_vector(31 downto 0);
108
   signal reg_destD      : std_logic_vector(31 downto 0);
109
   signal a_bus          : std_logic_vector(31 downto 0);
110
   signal a_busD         : std_logic_vector(31 downto 0);
111
   signal b_bus          : std_logic_vector(31 downto 0);
112
   signal b_busD         : std_logic_vector(31 downto 0);
113
   signal c_bus          : std_logic_vector(31 downto 0);
114
   signal c_alu          : std_logic_vector(31 downto 0);
115
   signal c_shift        : std_logic_vector(31 downto 0);
116
   signal c_mult         : std_logic_vector(31 downto 0);
117
   signal c_memory       : std_logic_vector(31 downto 0);
118 39 rhoads
   signal imm            : std_logic_vector(15 downto 0);
119
   signal pc             : std_logic_vector(31 downto 0);
120
   signal pc_plus4       : std_logic_vector(31 downto 0);
121 73 rhoads
   signal alu_func       : alu_function_type;
122
   signal alu_funcD      : alu_function_type;
123
   signal shift_func     : shift_function_type;
124
   signal shift_funcD    : shift_function_type;
125
   signal mult_func      : mult_function_type;
126
   signal mult_funcD     : mult_function_type;
127
   signal branch_func    : branch_function_type;
128 39 rhoads
   signal take_branch    : std_logic;
129
   signal a_source       : a_source_type;
130
   signal b_source       : b_source_type;
131
   signal c_source       : c_source_type;
132
   signal pc_source      : pc_source_type;
133
   signal mem_source     : mem_source_type;
134
   signal pause_mult     : std_logic;
135 73 rhoads
   signal pause_ctrl     : std_logic;
136
   signal pause_pipeline : std_logic;
137
   signal pause_any      : std_logic;
138
   signal pause_non_ctrl : std_logic;
139
   signal pause_bank     : std_logic;
140 39 rhoads
   signal nullify_op     : std_logic;
141
   signal intr_enable    : std_logic;
142
   signal intr_signal    : 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 96 rhoads
   nullify_op <= '1' when pc_source = from_lbranch and take_branch = '0' else '0';
151 39 rhoads
   c_bus <= c_alu or c_shift or c_mult;
152 73 rhoads
   reset <= '1' when reset_in = '1' or reset_reg /= "1111" else '0';
153 39 rhoads
 
154 73 rhoads
   --synchronize reset and interrupt pins
155 83 rhoads
   intr_proc: process(clk, reset_in, reset_reg, intr_in, intr_enable,
156
      pc_source, pc, pause_any)
157 73 rhoads
   begin
158
      if reset_in = '1' then
159
         reset_reg <= "0000";
160
      elsif rising_edge(clk) then
161
         if reset_reg /= "1111" then
162
            reset_reg <= reset_reg + 1;
163
         end if;
164
         --don't try to interrupt a multi-cycle instruction
165
         if intr_in = '1' and intr_enable = '1' and
166
               pc_source = from_inc4 and pc(2) = '0' and
167
               pause_any = '0' then
168
            --the epc will be backed up one opcode (pc-4)
169
            intr_signal <= '1';
170
         else
171
            intr_signal <= '0';
172
         end if;
173
      end if;
174
   end process;
175 39 rhoads
 
176
   u1_pc_next: pc_next PORT MAP (
177
        clk          => clk,
178 60 rhoads
        reset_in     => reset,
179 96 rhoads
        take_branch  => take_branch,
180 73 rhoads
        pause_in     => pause_any,
181
        pc_new       => c_bus(31 downto 2),
182 39 rhoads
        opcode25_0   => opcode(25 downto 0),
183
        pc_source    => pc_source,
184
        pc_out       => pc,
185
        pc_out_plus4 => pc_plus4);
186
 
187 73 rhoads
   u2_mem_ctrl: mem_ctrl
188
      generic map (ACCURATE_TIMING => accurate_timing)
189
      PORT MAP (
190 39 rhoads
        clk          => clk,
191 60 rhoads
        reset_in     => reset,
192 73 rhoads
        pause_in     => pause_non_ctrl,
193 39 rhoads
        nullify_op   => nullify_op,
194
        address_pc   => pc,
195
        opcode_out   => opcode,
196
 
197 73 rhoads
        address_data => c_bus,
198 39 rhoads
        mem_source   => mem_source,
199
        data_write   => reg_target,
200
        data_read    => c_memory,
201 73 rhoads
        pause_out    => pause_ctrl,
202 39 rhoads
 
203
        mem_address  => mem_address,
204
        mem_data_w   => mem_data_w,
205
        mem_data_r   => mem_data_r,
206
        mem_byte_sel => mem_byte_sel,
207 73 rhoads
        mem_write    => mem_write);
208 39 rhoads
 
209
   u3_control: control PORT MAP (
210
        opcode       => opcode,
211
        intr_signal  => intr_signal,
212
        rs_index     => rs_index,
213
        rt_index     => rt_index,
214
        rd_index     => rd_index,
215
        imm_out      => imm,
216 73 rhoads
        alu_func     => alu_func,
217
        shift_func   => shift_func,
218
        mult_func    => mult_func,
219
        branch_func  => branch_func,
220 39 rhoads
        a_source_out => a_source,
221
        b_source_out => b_source,
222
        c_source_out => c_source,
223
        pc_source_out=> pc_source,
224
        mem_source_out=> mem_source);
225
 
226 47 rhoads
   u4_reg_bank: reg_bank
227
      generic map(memory_type => memory_type)
228
      port map (
229 39 rhoads
        clk            => clk,
230 60 rhoads
        reset_in       => reset,
231 73 rhoads
        pause          => pause_bank,
232 39 rhoads
        rs_index       => rs_index,
233
        rt_index       => rt_index,
234 73 rhoads
        rd_index       => rd_indexD,
235 39 rhoads
        reg_source_out => reg_source,
236
        reg_target_out => reg_target,
237 73 rhoads
        reg_dest_new   => reg_destD,
238 39 rhoads
        intr_enable    => intr_enable);
239
 
240
   u5_bus_mux: bus_mux port map (
241
        imm_in       => imm,
242
        reg_source   => reg_source,
243
        a_mux        => a_source,
244
        a_out        => a_bus,
245
 
246
        reg_target   => reg_target,
247
        b_mux        => b_source,
248
        b_out        => b_bus,
249
 
250
        c_bus        => c_bus,
251
        c_memory     => c_memory,
252
        c_pc         => pc,
253
        c_pc_plus4   => pc_plus4,
254
        c_mux        => c_source,
255
        reg_dest_out => reg_dest,
256
 
257 73 rhoads
        branch_func  => branch_func,
258 39 rhoads
        take_branch  => take_branch);
259
 
260 47 rhoads
   u6_alu: alu
261 114 rhoads
      generic map (adder_type => adder_type,
262
                   alu_type   => alu_type)
263 47 rhoads
      port map (
264 73 rhoads
        a_in         => a_busD,
265
        b_in         => b_busD,
266
        alu_function => alu_funcD,
267 39 rhoads
        c_alu        => c_alu);
268
 
269 114 rhoads
   u7_shifter: shifter
270
      generic map (shifter_type => shifter_type)
271
      port map (
272 73 rhoads
        value        => b_busD,
273
        shift_amount => a_busD(4 downto 0),
274
        shift_func   => shift_funcD,
275 39 rhoads
        c_shift      => c_shift);
276
 
277 47 rhoads
   u8_mult: mult
278 114 rhoads
      generic map (adder_type => adder_type,
279
                   mult_type  => mult_type)
280 47 rhoads
      port map (
281 39 rhoads
        clk       => clk,
282 73 rhoads
        a         => a_busD,
283
        b         => b_busD,
284
        mult_func => mult_funcD,
285 39 rhoads
        c_mult    => c_mult,
286
        pause_out => pause_mult);
287
 
288 73 rhoads
   pipeline2: if pipeline_stages <= 2 generate
289
      a_busD <= a_bus;
290
      b_busD <= b_bus;
291
      alu_funcD <= alu_func;
292
      shift_funcD <= shift_func;
293
      mult_funcD <= mult_func;
294
      rd_indexD <= rd_index;
295
 
296
      reg_destD <= reg_dest;
297
      pause_pipeline <= '0';
298
   end generate; --pipeline2
299
 
300
   pipeline3: if pipeline_stages >= 3 generate
301
      --When operating in three stage pipeline mode, the following signals
302
      --are delayed by one clock cycle:  a_bus, b_bus, alu/shift/mult_func,
303
      --c_source, and rd_index.
304
   u9_pipeline: pipeline port map (
305
        clk            => clk,
306
        reset          => reset,
307
        a_bus          => a_bus,
308
        a_busD         => a_busD,
309
        b_bus          => b_bus,
310
        b_busD         => b_busD,
311
        alu_func       => alu_func,
312
        alu_funcD      => alu_funcD,
313
        shift_func     => shift_func,
314
        shift_funcD    => shift_funcD,
315
        mult_func      => mult_func,
316
        mult_funcD     => mult_funcD,
317
        reg_dest       => reg_dest,
318
        reg_destD      => reg_destD,
319
        rd_index       => rd_index,
320
        rd_indexD      => rd_indexD,
321
 
322
        rs_index       => rs_index,
323
        rt_index       => rt_index,
324
        pc_source      => pc_source,
325
        mem_source     => mem_source,
326
        a_source       => a_source,
327
        b_source       => b_source,
328
        c_source       => c_source,
329
        c_bus          => c_bus,
330
        pause_any      => pause_any,
331
        pause_pipeline => pause_pipeline);
332
   end generate; --pipeline3
333
 
334 39 rhoads
end; --architecture logic
335
 

powered by: WebSVN 2.1.0

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