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

Subversion Repositories ppx16

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 jesus
--
2
-- PIC16xx compatible microcontroller core
3
--
4 15 jesus
-- Version : 0232
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 15 jesus
--      0232 : Fixed bank decoding and FSR/PCLATH register access
50 3 jesus
 
51
library IEEE;
52
use IEEE.std_logic_1164.all;
53
use IEEE.numeric_std.all;
54
use work.PPX_Pack.all;
55
 
56
entity PPX16 is
57
        generic(
58
                InstructionLength       : integer;
59
                ROMAddressWidth         : integer;
60
                StackAddrWidth          : integer;
61
                TopBoot                         : boolean
62
        );
63
        port(
64
                Clk                     : in std_logic;
65
                Reset_n         : in std_logic;
66
                ROM_Addr        : out std_logic_vector(ROMAddressWidth - 1 downto 0);
67
                ROM_Data        : in std_logic_vector(InstructionLength - 1 downto 0);
68
                Int_Trig        : in std_logic;
69
                GIE                     : in std_logic;
70
                Int_Acc         : out std_logic;
71
                Int_Ret         : out std_logic;
72
                File_Addr       : out std_logic_vector(InstructionLength - 6 downto 0);
73
                File_Addr_r     : out std_logic_vector(InstructionLength - 6 downto 0);
74
                File_Wr         : out std_logic;
75 11 jesus
                W_Wr            : out std_logic;
76 3 jesus
                Instruction     : out std_logic_vector(InstructionLength - 1 downto 0);
77 11 jesus
                Op_Bus          : in std_logic_vector(7 downto 0);
78
                W                       : out std_logic_vector(7 downto 0);
79
                STATUS          : out std_logic_vector(7 downto 0);
80
                FSR                     : out std_logic_vector(7 downto 0);
81
                PCLATH          : out std_logic_vector(4 downto 0);
82
                Res_Bus         : out std_logic_vector(7 downto 0)
83 3 jesus
        );
84
end PPX16;
85
 
86
architecture rtl of PPX16 is
87
 
88
        -- File control
89
        signal  File_Addr_i             : std_logic_vector(InstructionLength - 6 downto 0);
90
        signal  File_Addr_i_r   : std_logic_vector(InstructionLength - 6 downto 0);
91
        signal  File_Wr_i               : std_logic;
92
        signal  PC_CS                   : std_logic;
93
 
94
        -- Registers
95 11 jesus
        signal  W_i                             : std_logic_vector(7 downto 0);
96 15 jesus
        signal  PCLATH_d                : std_logic_vector(4 downto 0);
97 11 jesus
        signal  PCLATH_i                : std_logic_vector(4 downto 0);
98
        signal  STATUS_i                : std_logic_vector(7 downto 0);
99 15 jesus
        signal  FSR_d                   : std_logic_vector(7 downto 0);
100 11 jesus
        signal  FSR_i                   : std_logic_vector(7 downto 0);
101 3 jesus
        signal  NPC                             : std_logic_vector(InstructionLength - 2 downto 0);
102
 
103
        -- Registered instruction word
104 11 jesus
        signal  Inst                    : std_logic_vector(InstructionLength - 1 downto 0);
105 3 jesus
 
106
        -- Control signals
107 11 jesus
        signal  Res_Bus_i               : std_logic_vector(7 downto 0);
108
        signal  Q                               : std_logic_vector(7 downto 0);
109 3 jesus
        signal  Op_Mux                  : std_logic_vector(7 downto 0);
110 11 jesus
        signal  STATUS_d_i              : std_logic_vector(7 downto 0);
111 3 jesus
        signal  STATUS_d                : std_logic_vector(2 downto 0);
112
        signal  STATUS_Wr               : std_logic_vector(2 downto 0);
113
        signal  Z_Skip                  : std_logic;
114
        signal  B_Skip                  : std_logic;
115
        signal  Inst_Skip               : std_logic;
116 11 jesus
        signal  W_Wr_i                  : std_logic;
117 3 jesus
        signal  Imm_Op                  : std_logic;
118
        signal  Push                    : std_logic;
119
        signal  Pop                             : std_logic;
120
        signal  Goto                    : std_logic;
121
        signal  IRet                    : std_logic;
122 11 jesus
        signal  A2Res                   : std_logic;
123 3 jesus
        signal  B2Res                   : std_logic;
124
        signal  Sleep                   : std_logic;
125
        signal  Sleep_r                 : std_logic;
126
        signal  Int                             : std_logic;
127 11 jesus
        signal  Int_Pending             : std_logic;
128 3 jesus
 
129 11 jesus
begin
130 3 jesus
 
131 11 jesus
        Int_Acc <= Int;
132
        W_Wr <= W_Wr_i;
133
        W <= W_i;
134
        STATUS <= STATUS_d_i;
135 15 jesus
        PCLATH <= PCLATH_d;
136
        FSR <= FSR_d;
137 11 jesus
 
138 3 jesus
        -- Instruction register
139
        Instruction <= Inst;
140
        process (Reset_n, Clk)
141
        begin
142
                if Reset_n = '0' then
143
                        Inst <= (others => '0'); -- Force NOP at reset.
144
                elsif Clk'event and Clk = '1' then
145
                        if Inst_Skip = '1' then
146
                                Inst <= (others => '0'); -- Flush (Force NOP)
147
                        else
148
                                Inst <= ROM_Data;
149
                        end if;
150
                end if;
151
        end process;
152
 
153
        -- File address
154
        File_Addr <= File_Addr_i;
155
        i12 : if InstructionLength = 12 generate
156 15 jesus
                File_Addr_i <= FSR_d(6 downto 0) when
157 3 jesus
-- pragma translate_off
158
                                        is_x(ROM_Data) or
159
-- pragma translate_on
160
                                        unsigned(ROM_Data(4 downto 0)) = 0 else
161 15 jesus
                                        FSR_d(6 downto 5) & ROM_Data(4 downto 0);
162 3 jesus
        end generate;
163
        i14 : if InstructionLength = 14 generate
164 15 jesus
                File_Addr_i <= STATUS_d_i(7) & FSR_d(7 downto 0) when
165 3 jesus
-- pragma translate_off
166
                                        is_x(ROM_Data) or
167
-- pragma translate_on
168
                                        unsigned(ROM_Data(6 downto 0)) = 0 else
169 15 jesus
                                        STATUS_d_i(6 downto 5) & ROM_Data(6 downto 0);
170 3 jesus
        end generate;
171
        process (Clk)
172
        begin
173
                if Clk'event and Clk = '1' then
174
                        File_Addr_r <= File_Addr_i;
175
                        File_Addr_i_r <= File_Addr_i;
176
                end if;
177
        end process;
178
 
179
        -- PCLATH Register
180 15 jesus
        PCLATH_d <= Res_Bus_i(4 downto 0) when
181
                to_integer(unsigned(File_Addr_i_r(6 downto 0))) = 10 and File_Wr_i = '1'
182
                else PCLATH_i;
183 3 jesus
        process (Reset_n, Clk)
184
        begin
185
                if Reset_n = '0' then
186 11 jesus
                        PCLATH_i <= "00000";
187 3 jesus
                elsif Clk'event and Clk = '1' then
188 15 jesus
                        PCLATH_i <= PCLATH_d;
189 3 jesus
                end if;
190
        end process;
191
 
192
        -- Working register
193
        process (Clk)
194
        begin
195
                if Clk'event and Clk = '1' then
196 11 jesus
                        if W_Wr_i = '1' then
197
                                W_i <= Res_Bus_i;
198 3 jesus
                        end if;
199
                end if;
200
        end process;
201
 
202
        -- Status register
203 15 jesus
        process (STATUS_Wr, STATUS_d, STATUS_i, A2Res, Op_Bus, File_Addr_i_r, File_Wr_i, Res_Bus_i)
204 11 jesus
        begin
205
                STATUS_d_i <= STATUS_i;
206
                if STATUS_Wr(0) = '1' then
207
                        STATUS_d_i(0) <= STATUS_d(0);
208
                end if;
209
                if STATUS_Wr(1) = '1' then
210
                        STATUS_d_i(1) <= STATUS_d(1);
211
                end if;
212
                if STATUS_Wr(2) = '1' then
213
                        STATUS_d_i(2) <= STATUS_d(2);
214
                end if;
215
                if A2Res = '1' then
216
                        STATUS_d_i(2) <= '0';
217
                        if Op_Bus = "00000000" then
218
                                STATUS_d_i(2) <= '1';
219
                        end if;
220
                end if;
221 15 jesus
                if to_integer(unsigned(File_Addr_i_r(InstructionLength - 8 downto 0))) = 3 and File_Wr_i = '1' then
222
                        STATUS_d_i <= Res_Bus_i;
223
                end if;
224 11 jesus
        end process;
225 3 jesus
        process (Reset_n, Clk)
226
        begin
227
                if Reset_n = '0' then
228 11 jesus
                        STATUS_i <= "00011000";
229 3 jesus
                elsif Clk'event and Clk = '1' then
230 15 jesus
                        STATUS_i <= STATUS_d_i;
231 3 jesus
                end if;
232
        end process;
233
 
234
        -- FSR Register
235 15 jesus
        FSR_d <= Res_Bus_i when
236
                to_integer(unsigned(File_Addr_i_r(InstructionLength - 8 downto 0))) = 4 and
237
                File_Wr_i = '1' else FSR_i;
238 3 jesus
        process (Reset_n, Clk)
239
        begin
240
                if Reset_n = '0' then
241 11 jesus
                        FSR_i <= "11111111";
242 3 jesus
                elsif Clk'event and Clk = '1' then
243 15 jesus
                        FSR_i <= FSR_d;
244 3 jesus
                end if;
245
        end process;
246
 
247
        -- Program counter
248
        PC_CS <= '1' when to_integer(unsigned(File_Addr_i_r(InstructionLength - 8 downto 0))) = 2 else '0';
249
        ROM_Addr <= NPC(ROMAddressWidth - 1 downto 0);
250
        pcs : PPX_PCS
251
                generic map(
252
                        PC_Width => InstructionLength - 1,
253
                        StackAddrWidth => StackAddrWidth,
254
                        TopBoot => TopBoot)
255
                port map(
256
                        Clk => Clk,
257
                        Reset_n => Reset_n,
258
                        CS => PC_CS,
259
                        Wr => File_Wr_i,
260 11 jesus
                        Data_In => Res_Bus_i,
261 3 jesus
                        Addr_In => Inst(InstructionLength - 4 downto 0),
262 11 jesus
                        PCLATH => PCLATH_i,
263
                        STATUS => STATUS_i(6 downto 5),
264 3 jesus
                        NPC => NPC,
265
                        Int => Int,
266
                        Sleep => Sleep_r,
267
                        Push => Push,
268
                        Pop => Pop,
269
                        Goto => Goto);
270
 
271
        -- ALU
272 11 jesus
        Op_Mux <= Inst(7 downto 0) when Imm_Op = '1' else W_i;
273
        Res_Bus <= Res_Bus_i;
274
        Res_Bus_i <= Op_Bus when A2Res = '1' else Op_Mux when B2Res = '1' else Q;
275 3 jesus
        alu : PPX_ALU
276
                generic map(InstructionLength => InstructionLength)
277
                port map(
278
                        Clk => Clk,
279
                        ROM_Data => ROM_Data,
280
                        A => Op_Bus,
281
                        B => Op_Mux,
282 11 jesus
                        Q => Q,
283 3 jesus
                        Skip => Inst_Skip,
284 11 jesus
                        Carry => STATUS_i(0),
285 3 jesus
                        Z_Skip => Z_Skip,
286
                        STATUS_d => STATUS_d,
287
                        STATUS_Wr => STATUS_Wr);
288
 
289
        -- Instruction decoder
290
        File_Wr <= File_Wr_i;
291 11 jesus
        Inst_Skip <= Z_Skip or B_Skip or Sleep_r or Int_Pending;
292 3 jesus
        id : PPX_Ctrl
293
                generic map(InstructionLength => InstructionLength)
294
                port map(
295 11 jesus
                        Clk => Clk,
296 14 jesus
                        Reset_n => Reset_n,
297 11 jesus
                        ROM_Data => ROM_Data,
298 3 jesus
                        Inst => Inst,
299 11 jesus
                        Skip => Inst_Skip,
300 3 jesus
                        File_Wr => File_Wr_i,
301 11 jesus
                        W_Wr => W_Wr_i,
302 3 jesus
                        Imm_Op => Imm_Op,
303 11 jesus
                        A2Res => A2Res,
304 3 jesus
                        B2Res => B2Res,
305
                        Push => Push,
306
                        Pop => Pop,
307
                        Goto => Goto,
308
                        IRet => IRet,
309
                        B_Skip => B_Skip,
310
                        Sleep => Sleep);
311
 
312 11 jesus
        -- Interrupt
313 3 jesus
        process (Reset_n, Clk)
314
        begin
315
                if Reset_n = '0' then
316
                        Sleep_r <= '0';
317
                        Int <= '0';
318 11 jesus
                        Int_Pending <= '0';
319 3 jesus
                        Int_Ret <= '0';
320
                elsif Clk'event and Clk = '1' then
321
                        if Sleep = '1' then
322
                                Sleep_r <= '1';
323
                        end if;
324
                        if Int_Trig = '1' then
325
                                Sleep_r <= '0';
326
                        end if;
327 11 jesus
                        Int_Pending <= '0';
328
                        Int <= '0';
329
                        if Int_Trig = '1' and GIE = '1' and Int = '0' then
330
                                Int_Pending <= '1';
331
                        end if;
332
                        if Int_Pending = '1' and Int = '0' and (Z_Skip or B_Skip or Sleep_r) = '0' then
333 3 jesus
                                Int <= '1';
334
                        end if;
335
                        if IRet = '1' then
336
                                Int_Ret <= '1';
337
                        else
338
                                Int_Ret <= '0';
339
                        end if;
340
                end if;
341
        end process;
342
 
343
end;

powered by: WebSVN 2.1.0

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