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

Subversion Repositories ppx16

[/] [ppx16/] [trunk/] [rtl/] [vhdl/] [PPX16.vhd] - Blame information for rev 14

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

Line No. Rev Author Line
1 3 jesus
--
2
-- PIC16xx compatible microcontroller core
3
--
4 14 jesus
-- Version : 0224
5 3 jesus
--
6
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
7
--
8
-- All rights reserved
9
--
10
-- Redistribution and use in source and synthezised forms, with or without
11
-- modification, are permitted provided that the following conditions are met:
12
--
13
-- Redistributions of source code must retain the above copyright notice,
14
-- this list of conditions and the following disclaimer.
15
--
16
-- Redistributions in synthesized form must reproduce the above copyright
17
-- notice, this list of conditions and the following disclaimer in the
18
-- documentation and/or other materials provided with the distribution.
19
--
20
-- Neither the name of the author nor the names of other contributors may
21
-- be used to endorse or promote products derived from this software without
22
-- specific prior written permission.
23
--
24
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
26
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
28
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
-- POSSIBILITY OF SUCH DAMAGE.
35
--
36
-- Please report bugs to the author, but before you do so, please
37
-- make sure that this is not a derivative work and that
38
-- you have the latest version of this file.
39
--
40
-- The latest version of this file can be found at:
41 14 jesus
--      http://www.opencores.org/cvsweb.shtml/ppx16/
42 3 jesus
--
43
-- Limitations :
44
--      Registers implemented in this entity are INDF, PCL, STATUS, FSR, (PCLATH)
45
--      other registers must be implemented externally including GPR
46
--
47
-- File history :
48
--
49
 
50
library IEEE;
51
use IEEE.std_logic_1164.all;
52
use IEEE.numeric_std.all;
53
use work.PPX_Pack.all;
54
 
55
entity PPX16 is
56
        generic(
57
                InstructionLength       : integer;
58
                ROMAddressWidth         : integer;
59
                StackAddrWidth          : integer;
60
                TopBoot                         : boolean
61
        );
62
        port(
63
                Clk                     : in std_logic;
64
                Reset_n         : in std_logic;
65
                ROM_Addr        : out std_logic_vector(ROMAddressWidth - 1 downto 0);
66
                ROM_Data        : in std_logic_vector(InstructionLength - 1 downto 0);
67
                Int_Trig        : in std_logic;
68
                GIE                     : in std_logic;
69
                Int_Acc         : out std_logic;
70
                Int_Ret         : out std_logic;
71
                File_Addr       : out std_logic_vector(InstructionLength - 6 downto 0);
72
                File_Addr_r     : out std_logic_vector(InstructionLength - 6 downto 0);
73
                File_Wr         : out std_logic;
74 11 jesus
                W_Wr            : out std_logic;
75 3 jesus
                Instruction     : out std_logic_vector(InstructionLength - 1 downto 0);
76 11 jesus
                Op_Bus          : in std_logic_vector(7 downto 0);
77
                W                       : out std_logic_vector(7 downto 0);
78
                STATUS          : out std_logic_vector(7 downto 0);
79
                FSR                     : out std_logic_vector(7 downto 0);
80
                PCLATH          : out std_logic_vector(4 downto 0);
81
                Res_Bus         : out std_logic_vector(7 downto 0)
82 3 jesus
        );
83
end PPX16;
84
 
85
architecture rtl of PPX16 is
86
 
87
        -- File control
88
        signal  File_Addr_i             : std_logic_vector(InstructionLength - 6 downto 0);
89
        signal  File_Addr_i_r   : std_logic_vector(InstructionLength - 6 downto 0);
90
        signal  File_Wr_i               : std_logic;
91
        signal  PC_CS                   : std_logic;
92
 
93
        -- Registers
94 11 jesus
        signal  W_i                             : std_logic_vector(7 downto 0);
95
        signal  PCLATH_i                : std_logic_vector(4 downto 0);
96
        signal  STATUS_i                : std_logic_vector(7 downto 0);
97
        signal  FSR_i                   : std_logic_vector(7 downto 0);
98 3 jesus
        signal  NPC                             : std_logic_vector(InstructionLength - 2 downto 0);
99
 
100
        -- Registered instruction word
101 11 jesus
        signal  Inst                    : std_logic_vector(InstructionLength - 1 downto 0);
102 3 jesus
 
103
        -- Control signals
104 11 jesus
        signal  Res_Bus_i               : std_logic_vector(7 downto 0);
105
        signal  Q                               : std_logic_vector(7 downto 0);
106 3 jesus
        signal  Op_Mux                  : std_logic_vector(7 downto 0);
107 11 jesus
        signal  STATUS_d_i              : std_logic_vector(7 downto 0);
108 3 jesus
        signal  STATUS_d                : std_logic_vector(2 downto 0);
109
        signal  STATUS_Wr               : std_logic_vector(2 downto 0);
110
        signal  Z_Skip                  : std_logic;
111
        signal  B_Skip                  : std_logic;
112
        signal  Inst_Skip               : std_logic;
113 11 jesus
        signal  W_Wr_i                  : std_logic;
114 3 jesus
        signal  Imm_Op                  : std_logic;
115
        signal  Push                    : std_logic;
116
        signal  Pop                             : std_logic;
117
        signal  Goto                    : std_logic;
118
        signal  IRet                    : std_logic;
119 11 jesus
        signal  A2Res                   : std_logic;
120 3 jesus
        signal  B2Res                   : std_logic;
121
        signal  Sleep                   : std_logic;
122
        signal  Sleep_r                 : std_logic;
123
        signal  Int                             : std_logic;
124 11 jesus
        signal  Int_Pending             : std_logic;
125 3 jesus
 
126 11 jesus
begin
127 3 jesus
 
128 11 jesus
        Int_Acc <= Int;
129
        W_Wr <= W_Wr_i;
130
        W <= W_i;
131
        STATUS <= STATUS_d_i;
132
        PCLATH <= PCLATH_i;
133
        FSR <= FSR_i;
134
 
135 3 jesus
        -- Instruction register
136
        Instruction <= Inst;
137
        process (Reset_n, Clk)
138
        begin
139
                if Reset_n = '0' then
140
                        Inst <= (others => '0'); -- Force NOP at reset.
141
                elsif Clk'event and Clk = '1' then
142
                        if Inst_Skip = '1' then
143
                                Inst <= (others => '0'); -- Flush (Force NOP)
144
                        else
145
                                Inst <= ROM_Data;
146
                        end if;
147
                end if;
148
        end process;
149
 
150
        -- File address
151
        File_Addr <= File_Addr_i;
152
        i12 : if InstructionLength = 12 generate
153 11 jesus
                File_Addr_i <= FSR_i(6 downto 0) when
154 3 jesus
-- pragma translate_off
155
                                        is_x(ROM_Data) or
156
-- pragma translate_on
157
                                        unsigned(ROM_Data(4 downto 0)) = 0 else
158 11 jesus
                                        FSR_i(6 downto 5) & ROM_Data(4 downto 0);
159 3 jesus
        end generate;
160
        i14 : if InstructionLength = 14 generate
161 11 jesus
                File_Addr_i <= STATUS_i(7) & FSR_i(7 downto 0) when
162 3 jesus
-- pragma translate_off
163
                                        is_x(ROM_Data) or
164
-- pragma translate_on
165
                                        unsigned(ROM_Data(6 downto 0)) = 0 else
166 11 jesus
                                        STATUS_i(6 downto 5) & ROM_Data(6 downto 0);
167 3 jesus
        end generate;
168
        process (Clk)
169
        begin
170
                if Clk'event and Clk = '1' then
171
                        File_Addr_r <= File_Addr_i;
172
                        File_Addr_i_r <= File_Addr_i;
173
                end if;
174
        end process;
175
 
176
        -- PCLATH Register
177
        process (Reset_n, Clk)
178
        begin
179
                if Reset_n = '0' then
180 11 jesus
                        PCLATH_i <= "00000";
181 3 jesus
                elsif Clk'event and Clk = '1' then
182
                        if to_integer(unsigned(File_Addr_i_r(6 downto 0))) = 10 and File_Wr_i = '1' then
183 11 jesus
                                PCLATH_i <= Res_Bus_i(4 downto 0);
184 3 jesus
                        end if;
185
                end if;
186
        end process;
187
 
188
        -- Working register
189
        process (Clk)
190
        begin
191
                if Clk'event and Clk = '1' then
192 11 jesus
                        if W_Wr_i = '1' then
193
                                W_i <= Res_Bus_i;
194 3 jesus
                        end if;
195
                end if;
196
        end process;
197
 
198
        -- Status register
199 11 jesus
        process (STATUS_Wr, STATUS_d, STATUS_i, A2Res, Op_Bus)
200
        begin
201
                STATUS_d_i <= STATUS_i;
202
                if STATUS_Wr(0) = '1' then
203
                        STATUS_d_i(0) <= STATUS_d(0);
204
                end if;
205
                if STATUS_Wr(1) = '1' then
206
                        STATUS_d_i(1) <= STATUS_d(1);
207
                end if;
208
                if STATUS_Wr(2) = '1' then
209
                        STATUS_d_i(2) <= STATUS_d(2);
210
                end if;
211
                if A2Res = '1' then
212
                        STATUS_d_i(2) <= '0';
213
                        if Op_Bus = "00000000" then
214
                                STATUS_d_i(2) <= '1';
215
                        end if;
216
                end if;
217
        end process;
218 3 jesus
        process (Reset_n, Clk)
219
        begin
220
                if Reset_n = '0' then
221 11 jesus
                        STATUS_i <= "00011000";
222 3 jesus
                elsif Clk'event and Clk = '1' then
223
                        if to_integer(unsigned(File_Addr_i_r(InstructionLength - 8 downto 0))) = 3 and
224
                                File_Wr_i = '1' then
225 11 jesus
                                STATUS_i <= Res_Bus_i;
226 3 jesus
                        else
227 11 jesus
                                STATUS_i <= STATUS_d_i;
228 3 jesus
                        end if;
229
                end if;
230
        end process;
231
 
232
        -- FSR Register
233
        process (Reset_n, Clk)
234
        begin
235
                if Reset_n = '0' then
236 11 jesus
                        FSR_i <= "11111111";
237 3 jesus
                elsif Clk'event and Clk = '1' then
238
                        if to_integer(unsigned(File_Addr_i_r(InstructionLength - 8 downto 0))) = 4 and
239
                                File_Wr_i = '1' then
240 11 jesus
                                FSR_i <= Res_Bus_i;
241 3 jesus
                        end if;
242
                end if;
243
        end process;
244
 
245
        -- Program counter
246
        PC_CS <= '1' when to_integer(unsigned(File_Addr_i_r(InstructionLength - 8 downto 0))) = 2 else '0';
247
        ROM_Addr <= NPC(ROMAddressWidth - 1 downto 0);
248
        pcs : PPX_PCS
249
                generic map(
250
                        PC_Width => InstructionLength - 1,
251
                        StackAddrWidth => StackAddrWidth,
252
                        TopBoot => TopBoot)
253
                port map(
254
                        Clk => Clk,
255
                        Reset_n => Reset_n,
256
                        CS => PC_CS,
257
                        Wr => File_Wr_i,
258 11 jesus
                        Data_In => Res_Bus_i,
259 3 jesus
                        Addr_In => Inst(InstructionLength - 4 downto 0),
260 11 jesus
                        PCLATH => PCLATH_i,
261
                        STATUS => STATUS_i(6 downto 5),
262 3 jesus
                        NPC => NPC,
263
                        Int => Int,
264
                        Sleep => Sleep_r,
265
                        Push => Push,
266
                        Pop => Pop,
267
                        Goto => Goto);
268
 
269
        -- ALU
270 11 jesus
        Op_Mux <= Inst(7 downto 0) when Imm_Op = '1' else W_i;
271
        Res_Bus <= Res_Bus_i;
272
        Res_Bus_i <= Op_Bus when A2Res = '1' else Op_Mux when B2Res = '1' else Q;
273 3 jesus
        alu : PPX_ALU
274
                generic map(InstructionLength => InstructionLength)
275
                port map(
276
                        Clk => Clk,
277
                        ROM_Data => ROM_Data,
278
                        A => Op_Bus,
279
                        B => Op_Mux,
280 11 jesus
                        Q => Q,
281 3 jesus
                        Skip => Inst_Skip,
282 11 jesus
                        Carry => STATUS_i(0),
283 3 jesus
                        Z_Skip => Z_Skip,
284
                        STATUS_d => STATUS_d,
285
                        STATUS_Wr => STATUS_Wr);
286
 
287
        -- Instruction decoder
288
        File_Wr <= File_Wr_i;
289 11 jesus
        Inst_Skip <= Z_Skip or B_Skip or Sleep_r or Int_Pending;
290 3 jesus
        id : PPX_Ctrl
291
                generic map(InstructionLength => InstructionLength)
292
                port map(
293 11 jesus
                        Clk => Clk,
294 14 jesus
                        Reset_n => Reset_n,
295 11 jesus
                        ROM_Data => ROM_Data,
296 3 jesus
                        Inst => Inst,
297 11 jesus
                        Skip => Inst_Skip,
298 3 jesus
                        File_Wr => File_Wr_i,
299 11 jesus
                        W_Wr => W_Wr_i,
300 3 jesus
                        Imm_Op => Imm_Op,
301 11 jesus
                        A2Res => A2Res,
302 3 jesus
                        B2Res => B2Res,
303
                        Push => Push,
304
                        Pop => Pop,
305
                        Goto => Goto,
306
                        IRet => IRet,
307
                        B_Skip => B_Skip,
308
                        Sleep => Sleep);
309
 
310 11 jesus
        -- Interrupt
311 3 jesus
        process (Reset_n, Clk)
312
        begin
313
                if Reset_n = '0' then
314
                        Sleep_r <= '0';
315
                        Int <= '0';
316 11 jesus
                        Int_Pending <= '0';
317 3 jesus
                        Int_Ret <= '0';
318
                elsif Clk'event and Clk = '1' then
319
                        if Sleep = '1' then
320
                                Sleep_r <= '1';
321
                        end if;
322
                        if Int_Trig = '1' then
323
                                Sleep_r <= '0';
324
                        end if;
325 11 jesus
                        Int_Pending <= '0';
326
                        Int <= '0';
327
                        if Int_Trig = '1' and GIE = '1' and Int = '0' then
328
                                Int_Pending <= '1';
329
                        end if;
330
                        if Int_Pending = '1' and Int = '0' and (Z_Skip or B_Skip or Sleep_r) = '0' then
331 3 jesus
                                Int <= '1';
332
                        end if;
333
                        if IRet = '1' then
334
                                Int_Ret <= '1';
335
                        else
336
                                Int_Ret <= '0';
337
                        end if;
338
                end if;
339
        end process;
340
 
341
end;

powered by: WebSVN 2.1.0

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