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

Subversion Repositories tisc

[/] [tisc/] [web_uploads/] [TISC.VHD] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 root
-- Tiny Instruction Set (TISC) VHDL CPU Core
2
-- Copyright Vincent Crabtree, 15th Nov 2001
3
--
4
-- My first attempt at processor design, thanks to :-
5
-- Tim Boscke - CPU8BIT2, Rockwell - 6502, Microchip - Pic
6
-- Jien Chung Lo - EL405 , Steve Scott - Tisc,
7
-- Giovanni Moretti - Intro to Asm
8
-- Uses 12 bit program word, and 8 bit data memory
9
 
10
-- 2 reg machine,accumulator based, with akku and index regs
11
-- Harvard architecture, uses return x so as to eliminate need of pmem
12
-- indirect instructions like 8051.
13
-- pc is 10 bits, akku and idx are 8 bit.
14
 
15
-- Has carry and zero flags,
16
-- three addressing modes:- immediate, indirect and reg.
17
-- seperate program and data memory for pipelining later...
18
 
19
-- Instructions coded as thus:-
20
 
21
 
22
-- Long instructions first - program jump.
23
-- Both store return address for subroutine calls, 1 deep stack.
24
-- 0 0 xxxxxxxxxx       jc      pmem10          ; if c==1, stack = pc, pc <- pmem10, fi
25
-- 0 1 xxxxxxxxxx       jz      pmem10          ; if z==1, stack = pc, pc <- pmem10, fi
26
 
27
-- Immediate ops
28
-- bits 9 and 8 select what to do
29
-- 1 00 0 xxxxxxxx              lda     #imm8           ; a= imm8, c=0,
30
-- 1 00 1 xxxxxxxx              ret     #imm8           ; a= imm8, pc = stack
31
 
32
-- 1 01 0 xxxxxxxx              adc     #imm8           ; add with carry imm8, cy and z set
33
-- 1 01 1 xxxxxxxx              adx     #imm8           ; add imm8 to idx reg, z=(a==0)
34
 
35
-- Indirect and alu ops
36
-- bit 9 selects indirect or alu ops
37
 
38
-- Indirect - bits 7 and 8 select what to do
39
-- 1 10 0 0  xxxxxxx    lda     [ix]    ; load a indirect data mem
40
-- 1 10 0 1  xxxxxxx    sta     [ix]    ; store a indirect data mem
41
 
42
-- register register
43
-- 1 10 1 0  xxxxxxx    tax             ; x = a,
44
-- 1 10 1 1  xxxxxxx    txa             ; a = x
45
 
46
-- Arithmetic ops use indirect addressing
47
-- all alu ops indirect, bits 7 and 8 select alu op.
48
-- 1 11 00  xxxxxxx     add     a,[ix]  ; add with carry
49
-- 1 11 01  xxxxxxx     sub     a,[ix]  ; a = a + ~[idx], inc a after for proper subtract
50
-- 1 11 10  xxxxxxx     and     a,[ix]  ; and mem contents into a
51
-- 1 11 11  xxxxxxx     nor     a,[ix]  ; nor
52
 
53
-- States.
54
-- 000  instruction decode
55
-- 010  load a indirect - lda [ix]
56
-- 011  stor a indirect - sta [ix]
57
-- 100  add a,[ix]
58
-- 101  sub a,[ix[
59
-- 110  and a,[ix]
60
-- 111  nor a,[ix]
61
 
62
library ieee;
63
use ieee.std_logic_1164.all;
64
use ieee.std_logic_unsigned.all; -- has adder built in
65
 
66
entity tisc is
67
        port(
68
                -- bus
69
                -- db only 8 bits wide on dmem side, 12 on pmem side.
70
                data            :       inout   std_logic_vector(11 downto 0);
71
                address         :       out     std_logic_vector(9 downto 0);
72
 
73
                -- control - active low
74
                rd                      :       out     std_logic;              -- dram
75
                wr                      :       out     std_logic;              -- dram
76
                psen            :       out     std_logic;      -- pmem
77
 
78
                -- machine control
79
                clock           :       in      std_logic;
80
                reset           :       in      std_logic);
81
end;
82
 
83
architecture cpu_arch of tisc is
84
        -- Program control
85
        signal  stack           :       std_logic_vector(9 downto 0);   -- stack, 1 deep
86
        signal  pc                      :       std_logic_vector(9 downto 0);   -- program counter
87
 
88
        -- Registers
89
        signal  akku    :       std_logic_vector(8 downto 0);   -- accumulator, cy is bit 8
90
        signal  idx             :       std_logic_vector(7 downto 0);   -- index reg
91
        signal  z               :       std_logic;                                              -- zero flag
92
 
93
        -- ALU controls
94
        signal  aluout          :       std_logic_vector(9 downto 0);   -- alu result
95
        signal  temp            :       std_logic_vector(8 downto 0);   -- temp storage for alu
96
        signal  aludest         :       std_logic_vector(1 downto 0);   -- output mux alu
97
        signal  aluop           :       std_logic_vector(1 downto 0);   -- alu operation
98
        signal  aluinput        :       std_logic_vector(9 downto 0);   -- input to alu
99
 
100
        -- machine control
101
        signal  states          :       std_logic_vector(2 downto 0);   -- state controller
102
 
103
begin -- start logic decleration
104
 
105
process(clock,reset)    -- sequential section
106
begin
107
                -- check if reset or not
108
                if(reset = '0' ) then   -- async reset parameters
109
                   -- how do I stop the annoying async error?
110
                   pc   <= (others => '0');-- reset
111
                   states <= (others => '0'); -- decode sub state
112
                   aludest  <= "01";            -- reset destination dest
113
 
114
                elsif rising_edge(clock) then   --      actual machine
115
 
116
                -- check state machine for indirect alu ops
117
                if( states(2) = '1') then
118
 
119
                        if( states(1 downto 0) = "01") then     --sub add ind
120
                                temp <= "0" & (Not data(7 downto 0));
121
                        else
122
                                temp <= "0" & data(7 downto 0);
123
                        end if;
124
 
125
                   aluop <= states(1 downto 0); -- 00 adc indirect
126
                                                                                -- 01 not add ind
127
                                                                                -- 10 and indirect
128
                                                                                -- 11 nor indirect
129
                   -- sort out muxers for alu
130
                   aludest <= "00";     -- akku destination
131
                   states <= "000";     -- decode
132
 
133
                else
134
 
135
                   -- States decode
136
                   case states(1 downto 0) is   -- action dependent on states
137
                   when "00" =>         -- instruction decode
138
 
139
                        -- increment pc first
140
                        temp <= "000000001";    -- inc
141
                        aludest <= "10";        -- pc and increment and idle
142
                        pc <= aluout;           -- get result
143
 
144
                        -- Now decode instr on data bus
145
                        -- sort out jz or jc
146
                        if( (data(11) = '0') and        -- top bit nought, sio a jump...
147
                                ( ((akku(8) = '1') and (data(10) = '0')) or -- JC
148
                                        ((z='1') and (data(10)='1'))) ) then -- Jz
149
                           stack <= pc;                                                 --return stack
150
                           pc <= data(9 downto 0);
151
                           -- states already at decode
152
 
153
                        else    -- top bit is one, so not a jump instruction...
154
                                case data(10 downto 9) is
155
                                when "01" => -- adc #imm/adx #imm
156
                                        temp <= "0" & data(7 downto 0);
157
                                        aluop <= "01";                          -- add
158
                                        aludest <= data(8) & data(8) ; --00 is akku, 11 is idx
159
                                        -- states already at decode
160
 
161
                                when "00" =>  -- lda #imm/ret #imm clear cy
162
                                        if( data(8) = '1' ) then        -- ret ##imm
163
                                                pc <= stack;
164
                                        end if;
165
                                        akku <= "0" & data(7 downto 0);
166
                                        -- states already at decode
167
 
168
                                when "10" =>    -- lda/store or reg/reg
169
                                        if( data(8) = '1') then -- ld ind /store ind
170
                                                states <= "01" & data(7);-- "010";
171
                                        -- reg/reg
172
                                        elsif( data(7) = '0') then      -- tax
173
                                                idx <= akku(7 downto 0);
174
                                        else    -- txa
175
                                                akku <= "0" & idx(7 downto 0);
176
                                        end if;
177
                           -- states already at decode
178
 
179
                                when "11" =>    -- add ind, and
180
                                        states <= "1" & data(8 downto 7); -- "100";       -- add/sub ind
181
                                                                                                          -- "110";     -- and/nor ind
182
                                when others =>
183
                                states <= "000";        -- if non of above, decode/nop
184
                                end case;       -- end of instruction decode
185
 
186
                        end if; -- jump if
187
 
188
                when "10" =>    -- lda [ix] - buses should be setup
189
                   akku <= "0" & data(7 downto 0);
190
                   states <= "000";     -- decode
191
 
192
                when "11" =>    -- sta [ix]
193
                   -- akku placed on data bus now
194
                   states <= "000";     -- decode
195
 
196
                when others =>
197
                   states <= "000";     -- decode
198
 
199
                end case; -- end of state decode
200
        end if; -- end of alu indirect if
201
end if;         -- rising edge if
202
 
203
 
204
        -- Sort out alu ops and source/destination regs
205
        case aludest is
206
                when "00" =>    -- destination is alu
207
                        akku <= aluout(8 downto 0);
208
                when "11" =>    -- alu destination is idx
209
                        idx <= aluout(7 downto 0);
210
                when others => null;
211
        end case; -- end of dest decode
212
 
213
end process;    -- end sequential section
214
 
215
        -- concurrent section
216
        z <= '1' when akku = "000000000" and reset='1' else '0'; -- nice nand here
217
 
218
        -- alu input muxer
219
        with aludest select
220
        aluinput <= ("0" & akku) when "00",
221
                                ("00" & idx) when "11",
222
                                pc      when "10",
223
                                ("0" & temp) when others;
224
 
225
        -- Decode and perform arithmetic ops
226
        with aluop select
227
                aluout <= aluinput + ("0" & temp) when "01",            -- add
228
                                        aluinput and ("0" & temp) when "10",    -- and
229
                                        aluinput nor ("0" & temp) when "11",    -- nor
230
                                        not ("0" & temp) when others;      -- any use?
231
 
232
        -- assign pins
233
        address <= pc when states = "000" else "00"&idx;
234
 
235
        data    <= ("000" & akku) when states = "011" else "ZZZZZZZZZZZZ";
236
 
237
        psen    <= '0' when states="000" else '1';        -- pmem read
238
 
239
        rd      <= '0' when (states(2)='1') or (states="010") else '1';         -- dmem read
240
        wr      <= '0' when states="011" else '1';        -- dmem write
241
 
242
end cpu_arch;
243
 
244
 

powered by: WebSVN 2.1.0

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