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

Subversion Repositories xucpu

[/] [xucpu/] [trunk/] [VHDL/] [datapath/] [datapath.vhdl] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 lcdsgmtr
-- Copyright 2015, Jürgen Defurne
2
--
3
-- This file is part of the Experimental Unstable CPU System.
4
--
5
-- The Experimental Unstable CPU System Is free software: you can redistribute
6
-- it and/or modify it under the terms of the GNU Lesser General Public License
7
-- as published by the Free Software Foundation, either version 3 of the
8
-- License, or (at your option) any later version.
9
--
10
-- The Experimental Unstable CPU System is distributed in the hope that it will
11
-- be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
12
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
13
-- General Public License for more details.
14
--
15
-- You should have received a copy of the GNU Lesser General Public License
16
-- along with Experimental Unstable CPU System. If not, see
17
-- http://www.gnu.org/licenses/lgpl.txt.
18
 
19
 
20
LIBRARY IEEE;
21
USE IEEE.STD_LOGIC_1164.ALL;
22
USE IEEE.NUMERIC_STD.ALL;
23
USE work.components.ALL;
24
 
25
LIBRARY unisim;
26
USE unisim.vcomponents.ALL;
27
 
28
ENTITY dp IS
29
  GENERIC (
30
    w_data : NATURAL := 16;
31
    w_regn : NATURAL := 5);
32
  PORT (reset     : IN  STD_LOGIC;
33
        clock     : IN  STD_LOGIC;
34
        reg_a     : IN  STD_LOGIC_VECTOR(w_regn - 1 DOWNTO 0);
35
        reg_b     : IN  STD_LOGIC_VECTOR(w_regn - 1 DOWNTO 0);
36
        reg_input : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
37
        op_sel    : IN  STD_LOGIC_VECTOR(3 DOWNTO 0);
38
        we        : IN  STD_LOGIC;
39
        pc_input  : IN  STD_LOGIC_VECTOR(1 DOWNTO 0);
40
        pc_load   : IN  STD_LOGIC;
41
        dr_load   : IN  STD_LOGIC;
42
        ar_load   : IN  STD_LOGIC;
43
        aa_load   : IN  STD_LOGIC;
44
        ab_load   : IN  STD_LOGIC;
45
        addr_sel  : IN  STD_LOGIC;
46
        zero      : OUT STD_LOGIC;
47
        n_zero    : OUT STD_LOGIC;
48
        data_in   : IN  STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0);
49
        data_out  : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0);
50
        addr_out  : OUT STD_LOGIC_VECTOR(w_data - 2 DOWNTO 0));
51
END dp;
52
 
53
ARCHITECTURE Behavioral OF dp IS
54
 
55
  CONSTANT zero_reg : UNSIGNED(w_data - 1 DOWNTO 0) := (OTHERS => '0');
56
  CONSTANT zero_add : UNSIGNED(w_data - 2 DOWNTO 0) := (OTHERS => '0');
57
  CONSTANT zero_pc  : UNSIGNED(63 DOWNTO 0)         := X"0000000000007FFE";
58
 
59
  TYPE register_array IS ARRAY(0 TO (2**w_regn) - 1) OF UNSIGNED(w_data - 1 DOWNTO 0);
60
 
61
  SIGNAL reg_data      : UNSIGNED(w_data - 1 DOWNTO 0);
62
  SIGNAL register_file : register_array;
63
  SIGNAL a_out, b_out  : UNSIGNED(w_data - 1 DOWNTO 0);
64
  SIGNAL y             : UNSIGNED(w_data - 1 DOWNTO 0);
65
 
66
  SIGNAL pc           : UNSIGNED(w_data - 2 DOWNTO 0);
67
  SIGNAL addr_out_reg : UNSIGNED(w_data - 2 DOWNTO 0);
68
  SIGNAL data_out_reg : UNSIGNED(w_data - 1 DOWNTO 0);
69
  SIGNAL a, b         : UNSIGNED(w_data - 1 DOWNTO 0);
70
  SIGNAL pc_sum       : UNSIGNED(w_data - 2 DOWNTO 0);
71
  SIGNAL pc_data      : UNSIGNED(w_data - 2 DOWNTO 0);
72
 
73
BEGIN
74
 
75
  -----------------------------------------------------------------------------
76
  -- Register input multiplexer
77
  -----------------------------------------------------------------------------
78
  -- The last bit of the multiplexer must be generated so that
79
  -- I1 => '0', because addresses are 15 bit.
80
  reg_mux :
81
  FOR i IN w_data - 1 DOWNTO 0 GENERATE
82
    cond_1 : IF i < (w_data - 1) GENERATE
83
      MUX : LUT6
84
        GENERIC MAP (INIT => X"FF00F0F0CCCCAAAA")
85
        PORT MAP(I0 => data_in(i),
86
                 I1 => pc(i),
87
                 I2 => y(i),
88
                 I3 => b_out(i),
89
                 I4 => reg_input(0),
90
                 I5 => reg_input(1),
91
                 O  => reg_data(i));
92
    END GENERATE cond_1;
93
    cond_2 : IF i = (w_data - 1) GENERATE
94
      MUX : LUT6
95
        GENERIC MAP (INIT => X"FF00F0F0CCCCAAAA")
96
        PORT MAP(I0 => data_in(i),
97
                 I1 => '0',
98
                 I2 => y(i),
99
                 I3 => b_out(i),
100
                 I4 => reg_input(0),
101
                 I5 => reg_input(1),
102
                 O  => reg_data(i));
103
    END GENERATE cond_2;
104
  END GENERATE reg_mux;
105
 
106
  -------------------------------------------------------------------------------
107
  ---- Data register processes
108
  -------------------------------------------------------------------------------
109
 
110
  -- purpose: This is the writing to the register file
111
  -- type   : sequential
112
  -- inputs : clock, reg_c
113
  -- outputs: register_file
114
  reg : PROCESS (clock)
115
  BEGIN  -- PROCESS reg
116
    IF rising_edge(clock) THEN          -- rising clock edge
117
 
118
      IF we = '1' THEN
119
        register_file(to_integer(UNSIGNED(reg_a))) <= reg_data;
120
      ELSE
121
        register_file(to_integer(UNSIGNED(reg_a))) <= register_file(to_integer(UNSIGNED(reg_a)));
122
      END IF;
123
 
124
    END IF;
125
  END PROCESS reg;
126
 
127
  -- purpose: Get contents of registers onto intermediate buses
128
  -- type   : combinational
129
  -- inputs : reg_a,reg_b
130
  -- outputs: a_out,b_bout
131
  reg_outputs : PROCESS (reg_a, reg_b, register_file)
132
  BEGIN  -- PROCESS reg_outputs
133
    a_out <= register_file(to_integer(UNSIGNED(reg_a)));
134
    b_out <= register_file(to_integer(UNSIGNED(reg_b)));
135
  END PROCESS reg_outputs;
136
 
137
  --REG1 : registers PORT MAP (
138
  --  reset    => reset,
139
  --  clock    => clock,
140
  --  reg_a    => reg_a,
141
  --  reg_b    => reg_b,
142
  --  we       => we,
143
  --  reg_data => reg_data,
144
  --  a_out    => a_out,
145
  --  b_out    => b_out);
146
 
147
  -- purpose: Put outputs of register into pipeline registers
148
  -- type   : sequential
149
  -- inputs : clock,reset,a_out,b_out,aa_load,ab_load,dr_load,ar_load
150
  -- outputs: a,b
151
  pipeline_to_alu : PROCESS (clock, reset)
152
  BEGIN  -- PROCESS pipeline_to_alu
153
    IF reset = '0' THEN
154
      a            <= zero_reg;
155
      b            <= zero_reg;
156
      data_out_reg <= zero_reg;
157
      addr_out_reg <= zero_add;
158
    ELSIF rising_edge(clock) THEN       -- rising clock edge
159
 
160
      IF a_out = zero_reg THEN
161
        zero   <= '1';
162
        n_zero <= '0';
163
      ELSE
164
        zero   <= '0';
165
        n_zero <= '1';
166
      END IF;
167
 
168
      IF aa_load = '1' THEN
169
        a <= a_out;
170
      ELSE
171
        a <= a;
172
      END IF;
173
 
174
      IF ab_load = '1' THEN
175
        b <= b_out;
176
      ELSE
177
        b <= b;
178
      END IF;
179
 
180
      IF dr_load = '1' THEN
181
        data_out_reg <= a_out;
182
      ELSE
183
        data_out_reg <= data_out_reg;
184
      END IF;
185
 
186
      IF ar_load = '1' THEN
187
        addr_out_reg <= b_out(w_data - 2 DOWNTO 0);
188
      ELSE
189
        addr_out_reg <= addr_out_reg;
190
      END IF;
191
    END IF;
192
  END PROCESS pipeline_to_alu;
193
 
194
  data_out <= STD_LOGIC_VECTOR(data_out_reg);
195
 
196
  -- purpose: simple ALU
197
  -- type   : combinational
198
  -- inputs : clock, reset, a, b, op_sel
199
  -- outputs: y
200
  alu : PROCESS (clock, reset)
201
  BEGIN  -- PROCESS alu
202
 
203
    IF reset = '0' THEN
204
      y <= X"0000";
205
    ELSIF rising_edge(clock) THEN
206
      CASE op_sel IS
207
        WHEN "0000" =>                  -- increment
208
          y <= a + 1;
209
        WHEN "0001" =>                  -- decrement
210
          y <= a - 1;
211
        WHEN "0010" =>                  -- test for zero
212
          y <= a;
213
        WHEN "0111" =>                  -- addition
214
          y <= a + b;
215
        WHEN "1000" =>                  -- subtract, compare
216
          y <= a - b;
217
        WHEN "1010" =>                  -- logical and
218
          y <= a AND b;
219
        WHEN "1011" =>                  -- logical or
220
          y <= a OR b;
221
        WHEN "1100" =>                  -- logical xor
222
          y <= a XOR b;
223
        WHEN "1101" =>                  -- logical not
224
          y <= NOT a;
225
        WHEN "1110" =>                  -- shift left logical
226
          y <= a SLL 1;
227
        WHEN "1111" =>                  -- shift right logical
228
          y <= a SRL 1;
229
        WHEN OTHERS =>
230
          y <= y;
231
      END CASE;
232
    END IF;
233
  END PROCESS alu;
234
 
235
  -----------------------------------------------------------------------------
236
  -- Program counter input multiplexer
237
  -----------------------------------------------------------------------------
238
  pc_mux :
239
  FOR i IN w_data - 2 DOWNTO 0 GENERATE
240
    MUX : LUT6
241
      GENERIC MAP (INIT => X"FF00F0F0CCCCAAAA")
242
      PORT MAP(I0 => pc_sum(i),
243
               I1 => data_in(i),
244
               I2 => a_out(i),
245
               I3 => '0',
246
               I4 => pc_input(0),
247
               I5 => pc_input(1),
248
               O  => pc_data(i));
249
  END GENERATE pc_mux;
250
 
251
  -----------------------------------------------------------------------------
252
  -- Address path processes
253
  -----------------------------------------------------------------------------
254
 
255
  pc_register : PROCESS (clock, reset)
256
  BEGIN  -- PROCESS adder_based
257
    IF reset = '0' THEN
258
      pc <= zero_pc(w_data - 2 DOWNTO 0);
259
    ELSIF rising_edge(clock) THEN
260
      IF pc_load = '1' THEN
261
        pc <= pc_data;
262
      ELSE
263
        pc <= pc;
264
      END IF;
265
    END IF;
266
  END PROCESS pc_register;
267
 
268
  -- purpose: Add 1 to address output
269
  -- type   : combinational
270
  -- inputs : pc
271
  -- outputs: address_sum
272
  adder : PROCESS (pc)
273
  BEGIN  -- PROCESS adder
274
    pc_sum <= pc + 1;
275
  END PROCESS adder;
276
 
277
  -----------------------------------------------------------------------------
278
  -- Address selection logic
279
  -----------------------------------------------------------------------------
280
 
281
  addr_mux :
282
  FOR i IN w_data - 2 DOWNTO 0 GENERATE
283
    MUX : LUT6
284
      GENERIC MAP (INIT => X"FF00F0F0CCCCAAAA")
285
      PORT MAP(I0 => pc(i),
286
               I1 => addr_out_reg(i),
287
               I2 => '0',
288
               I3 => '0',
289
               I4 => addr_sel,
290
               I5 => '0',
291
               O  => addr_out(i));
292
  END GENERATE addr_mux;
293
 
294
END Behavioral;
295
 

powered by: WebSVN 2.1.0

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