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

Subversion Repositories RISCMCU

[/] [RISCMCU/] [trunk/] [vhdl/] [v_controlunit.vhd] - Blame information for rev 28

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 yapzihe
----------------------------------------------------------------------------
2
----                                                                    ----
3
---- WISHBONE RISCMCU IP Core                                           ----
4
----                                                                    ----
5
---- This file is part of the RISCMCU project                           ----
6
---- http://www.opencores.org/projects/riscmcu/                         ----
7
----                                                                    ----
8
---- Description                                                        ----
9
---- Implementation of a RISC Microcontroller based on Atmel AVR        ----
10
---- AT90S1200 instruction set and features with Altera Flex10k20 FPGA. ----
11
----                                                                    ----
12
---- Author(s):                                                         ----
13
----    - Yap Zi He, yapzihe@hotmail.com                                ----
14
----                                                                    ----
15
----------------------------------------------------------------------------
16
----                                                                    ----
17
---- Copyright (C) 2001 Authors and OPENCORES.ORG                       ----
18
----                                                                    ----
19
---- This source file may be used and distributed without               ----
20
---- restriction provided that this copyright statement is not          ----
21
---- removed from the file and that any derivative work contains        ----
22
---- the original copyright notice and the associated disclaimer.       ----
23
----                                                                    ----
24
---- This source file is free software; you can redistribute it         ----
25
---- and/or modify it under the terms of the GNU Lesser General         ----
26
---- Public License as published by the Free Software Foundation;       ----
27
---- either version 2.1 of the License, or (at your option) any         ----
28
---- later version.                                                     ----
29
----                                                                    ----
30
---- This source is distributed in the hope that it will be             ----
31
---- useful, but WITHOUT ANY WARRANTY; without even the implied         ----
32
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR            ----
33
---- PURPOSE. See the GNU Lesser General Public License for more        ----
34
---- details.                                                           ----
35
----                                                                    ----
36
---- You should have received a copy of the GNU Lesser General          ----
37
---- Public License along with this source; if not, download it         ----
38
---- from http://www.opencores.org/lgpl.shtml                           ----
39
----                                                                    ----
40
----------------------------------------------------------------------------
41
 
42
library ieee;
43
use ieee.std_logic_1164.all;
44
use ieee.std_logic_unsigned.all;
45
use ieee.std_logic_arith.all;
46
 
47
entity v_controlunit is
48
 port(  ir      : in std_logic_vector(15 downto 0);
49
                sr : in std_logic_vector(7 downto 0);
50
                clk, clrn : in std_logic;
51
                skip, extirq, timerirq : in std_logic;
52
 
53
                en : buffer std_logic;
54
                wr_reg : buffer std_logic;
55
                rd_ram, wr_ram, ld_mar, ld_mbr, inc_zp, dec_zp : out std_logic;
56
                sren : out std_logic_vector (6 downto 0);
57
 
58
                c2a,c2b : out std_logic;
59
                asel : out integer range 0 to 1;
60
                bsel : out integer range 0 to 3;
61
                bitsel : out integer range 0 to 7;
62
                set : out std_logic;
63
 
64
                add, subcp, logic, right, dir, pass_a : out std_logic;
65
 
66
                wcarry : out std_logic;
67
                logicsel : out integer range 0 to 3;
68
                rightsel : out integer range 0 to 2;
69
                dirsel : out integer range 0 to 1;
70
 
71
                addoffset : out std_logic;
72
                push, pull : out std_logic;
73
 
74
                cpse, skiptest : out std_logic;
75
 
76
                bclr,bset : out std_logic;
77
                bld : out std_logic;
78
 
79
                cbisbi : out std_logic;
80
 
81
                vec2, vec4 : buffer std_logic;
82
 
83
                dest : out integer range 0 to 15;
84
                srsel : out integer range 0 to 7;
85
                offset : out std_logic_vector(8 downto 0);
86
 
87
                clr_i, set_i, clr_intf, clr_tov0 : out std_logic;
88
 
89
                rd_sreg, wr_sreg : out std_logic;
90
                rd_gimsk, wr_gimsk, rd_timsk, wr_timsk, rd_tifr,wr_tifr : out std_logic;
91
                rd_mcucr,wr_mcucr, rd_tccr0, wr_tccr0, rd_tcnt0,wr_tcnt0 : out std_logic;
92
                rd_portb, wr_portb, rd_ddrb, wr_ddrb, rd_pinb : out std_logic;
93
                rd_portc, wr_portc, rd_ddrc, wr_ddrc, rd_pinc : out std_logic;
94
                rd_portd, wr_portd, rd_ddrd, wr_ddrd, rd_pind : out std_logic
95
 
96
);
97
end v_controlunit;
98
 
99
architecture controlunit of v_controlunit is
100
 
101
type statetype is (exes, nop2s, nop1s, lds, sts, cbisbis, sbicss, sleeps);
102
 
103
signal ibr : std_logic_vector(11 downto 0);
104
signal state : statetype;
105
signal one, neg, imm : std_logic;
106
 
107
signal
108
cpcm, sbcm, addm, cpsem, cpm, subm, adcm, andm, eorm, orm, movm,
109
cpim, sbcim, subim, orim, andim, ldm, stm, comm, negm, swapm, incm,
110
asrm, lsrm, rorm, decm, bsetm, bclrm, retm, retim, sleepm,
111
cbisbim, sbicsm, inm, outm, rjmpm, rcallm, ldim,
112
brbcsm, bldm, bstm, sbrcsm,
113
ld_incm, ld_decm, st_incm, st_decm : std_logic;
114
 
115
signal ioaddr : integer range 0 to 16#3f#;
116
signal rd_io, wr_io, break, irq, get_io, wr_ram_fast, branchtest, branch, jmp : std_logic;
117
 
118
        component v_iodecoder
119
         port(  ioaddr : in integer range 0 to 16#3f#;
120
                        rd_io, wr_io : in std_logic;
121
                        rd_sreg, wr_sreg : out std_logic;
122
                        rd_gimsk, wr_gimsk, rd_timsk, wr_timsk, rd_tifr,wr_tifr : out std_logic;
123
                        rd_mcucr,wr_mcucr, rd_tccr0, wr_tccr0, rd_tcnt0,wr_tcnt0 : out std_logic;
124
                        rd_portb, wr_portb, rd_ddrb, wr_ddrb, rd_pinb : out std_logic;
125
                        rd_portc, wr_portc, rd_ddrc, wr_ddrc, rd_pinc : out std_logic;
126
                        rd_portd, wr_portd, rd_ddrd, wr_ddrd, rd_pind : out std_logic
127
         );
128
        end component;
129
 
130
begin
131
 
132
-- Instruction Decoder
133
-- Decode 51 instructions generate 46 'm signals
134
-- Combine brbcs+brbs (brbcs) cbi+sbi (cbisbi)  sbrc+sbrs (sbrcs)  sbic+sbis (sbics)
135
 
136
process(ir, wr_reg, get_io, ibr)
137
begin
138
 
139
cpcm <= '0'; sbcm <= '0'; addm <= '0';
140
cpsem <= '0'; cpm <= '0'; subm <= '0'; adcm <= '0';
141
andm <= '0'; eorm <= '0'; orm <= '0'; movm <= '0';
142
cpim <= '0'; sbcim <= '0'; subim <= '0'; orim <= '0'; andim <= '0';
143
ldm <= '0'; stm <= '0'; comm <= '0'; negm <= '0'; swapm <= '0'; incm <= '0';
144
asrm <= '0'; lsrm <= '0'; rorm <= '0'; decm <= '0';
145
bsetm <= '0'; bclrm <= '0'; retm <= '0'; retim <= '0'; sleepm <= '0';
146
cbisbim <= '0'; sbicsm <= '0';
147
inm <= '0'; outm <= '0'; rjmpm <= '0'; rcallm <= '0'; ldim <= '0';
148
brbcsm <= '0'; bldm <= '0'; bstm <= '0'; sbrcsm <= '0';
149
ld_incm <= '0'; ld_decm <= '0'; st_incm <= '0'; st_decm <= '0';
150
 
151
case ir(15 downto 12) is
152
        when "0000" =>
153
                if ir(11 downto 10) = "01" then cpcm <= '1'; end if;
154
                if ir(11 downto 10) = "10" then sbcm <= '1'; end if;
155
                if ir(11 downto 10) = "11" then addm <= '1'; end if;
156
        when "0001" =>
157
                if ir(11 downto 10) = "00" then cpsem<= '1'; end if;
158
                if ir(11 downto 10) = "01" then cpm  <= '1'; end if;
159
                if ir(11 downto 10) = "10" then subm <= '1'; end if;
160
                if ir(11 downto 10) = "11" then adcm <= '1'; end if;
161
        when "0010" =>
162
                if ir(11 downto 10) = "00" then andm <= '1'; end if;
163
                if ir(11 downto 10) = "01" then eorm <= '1'; end if;
164
                if ir(11 downto 10) = "10" then orm  <= '1'; end if;
165
                if ir(11 downto 10) = "11" then movm <= '1'; end if;
166
        when "0011" =>
167
                cpim <= '1';
168
        when "0100" =>
169
                sbcim <= '1';
170
        when "0101" =>
171
                subim <= '1';
172
        when "0110" =>
173
                orim <= '1';
174
        when "0111" =>
175
                andim <= '1';
176
        when "1000" =>
177
                if ir(11 downto 9) = "000" then ldm <= '1'; end if;
178
                if ir(11 downto 9) = "001" then stm <= '1'; end if;
179
        when "1001" =>
180
                if ir(11 downto 9) = "000" then
181
                        if ir(1 downto 0) = "01" then ld_incm <= '1'; end if;
182
                        if ir(1 downto 0) = "10" then ld_decm <= '1'; end if;
183
                end if;
184
                if ir(11 downto 9) = "001" then
185
                        if ir(1 downto 0) = "01" then st_incm <= '1'; end if;
186
                        if ir(1 downto 0) = "10" then st_decm <= '1'; end if;
187
                end if;
188
                if ir(11 downto 9) = "010" then
189
                        case ir(3 downto 0) is
190
                                when "0000" => comm <= '1';
191
                                when "0001" => negm <= '1';
192
                                when "0010" => swapm <= '1';
193
                                when "0011" => incm <= '1';
194
                                when "0101" => asrm <= '1';
195
                                when "0110" => lsrm <= '1';
196
                                when "0111" => rorm <= '1';
197
                                when "1010" => decm <= '1';
198
                                when "1000" =>
199
                                        if ir(8 downto 7) = "00"  then bsetm  <= '1'; end if;
200
                                        if ir(8 downto 7) = "01"  then bclrm  <= '1'; end if;
201
                                        if ir(8 downto 7) & ir(4) = "100" then retm   <= '1'; end if;
202
                                        if ir(8 downto 7) & ir(4) = "101" then retim  <= '1'; end if;
203
                                        if ir(8 downto 7) = "11"  then sleepm <= '1'; end if;
204
                                when others =>
205
                        end case;
206
                elsif ir(11 downto 10) = "10" then
207
                        if ir(8) = '0' then cbisbim <= '1'; -- cbi, sbi
208
                        else sbicsm <= '1';  end if; -- sbic, sbis
209
                end if;
210
        when "1011" =>
211
                if ir(11) = '0' then inm  <= '1';
212
                else outm <= '1';
213
                end if;
214
        when "1100" =>
215
                rjmpm <= '1';
216
        when "1101" =>
217
                rcallm <= '1';
218
        when "1110" =>
219
                ldim <= '1';
220
        when "1111" =>
221
                if ir(11) = '0' then brbcsm <= '1'; end if;
222
                if ir(11 downto 9) = "100" then bldm  <= '1'; end if;
223
                if ir(11 downto 9) = "101" then bstm  <= '1'; end if;
224
                if ir(11 downto 10) = "11" then sbrcsm <= '1';  end if;-- sbrc, sbrs
225
        when others =>
226
end case;
227
 
228
 
229
-- Generate Fetch Stage Signals : C2A and C2B (C2A active also when fetch I/O)
230
if ((ibr(7 downto 4) = ir(7 downto 4)) and wr_reg = '1') or get_io = '1' then
231
        c2a <= '1';
232
else
233
        c2a <= '0';
234
end if;
235
 
236
if (ibr(7 downto 4) = ir(3 downto 0)) and wr_reg = '1' then
237
        c2b <= '1';
238
else
239
        c2b <= '0';
240
end if;
241
 
242
end process;
243
 
244
-- Generate wcarry, logicsel, rightsel and dirsel
245
-- Load IBR with IR when EN active
246
process(clk,clrn)
247
begin
248
if clrn = '0' then
249
        ibr <= "000000000000";
250
 
251
        wcarry <= '0';
252
        logicsel <= 0;
253
        rightsel <= 0;
254
        dirsel <= 0;
255
 
256
elsif clk'event and clk = '1' then
257
        if en = '1' then
258
                ibr <= ir(11 downto 0);
259
        end if;
260
 
261
        wcarry <= adcm or sbcm or sbcim or cpcm;
262
 
263
        if    orm = '1' or orim = '1' then logicsel <= 1;
264
        elsif eorm = '1' then logicsel <= 2;
265
        elsif comm = '1' then logicsel <= 3;
266
        else logicsel <= 0;
267
        end if;
268
 
269
        if    rorm = '1' then rightsel <= 1;
270
        elsif asrm = '1' then rightsel <= 2;
271
        else rightsel <= 0;
272
        end if;
273
 
274
        if swapm = '1' then dirsel <= 1;
275
        else dirsel <= 0;
276
        end if;
277
 
278
end if;
279
end process;
280
 
281
 
282
-- Finite State Machine
283
 
284
irq <= (timerirq or extirq) and sr(7);
285
break <= branch or skip or irq;
286
 
287
process(clk, clrn)
288
begin
289
 
290
if clrn = '0' then
291
 
292
        state <= exes;
293
 
294
        en <= '1';      get_io <= '0';
295
        pass_a <= '0'; wr_reg <= '0'; sren <= "0000000";
296
        rd_io <= '0'; wr_io <= '0'; rd_ram <= '0'; wr_ram_fast <= '0';
297
        ld_mar <= '0'; ld_mbr <= '0'; inc_zp <= '0'; dec_zp <= '0';
298
        add <= '0'; subcp <= '0'; logic <= '0';    right <= '0'; dir <= '0';
299
        jmp <= '0'; push <= '0'; pull <= '0';      branchtest <= '0';
300
        bclr <= '0'; bset <= '0'; bld <= '0';
301
        cpse <= '0'; skiptest <= '0';
302
        cbisbi <= '0';
303
        vec2 <= '0'; vec4 <= '0'; set_i <= '0';
304
 
305
elsif clk'event and clk = '1' then
306
 
307
        en <= '1';      get_io <= '0';
308
        pass_a <= '0'; wr_reg <= '0'; sren <= "0000000";
309
        rd_io <= '0'; wr_io <= '0'; rd_ram <= '0'; wr_ram_fast <= '0';
310
        ld_mar <= '0'; ld_mbr <= '0'; inc_zp <= '0'; dec_zp <= '0';
311
        add <= '0'; subcp <= '0'; logic <= '0';    right <= '0'; dir <= '0';
312
        jmp <= '0'; push <= '0'; pull <= '0';      branchtest <= '0';
313
        bclr <= '0'; bset <= '0'; bld <= '0';
314
        cpse <= '0'; skiptest <= '0';
315
        cbisbi <= '0';
316
        vec2 <= '0'; vec4 <= '0'; set_i <= '0';
317
 
318
        case state is
319
 
320
                when exes =>
321
 
322
                        if break = '1' then
323
 
324
                                if      branch = '1' then
325
                                        state <= nop1s;
326
 
327
                                elsif skip = '1' then
328
 
329
                                elsif irq = '1' then
330
                                        state <= nop2s;
331
                                        push <= '1';
332
                                        if extirq = '1' then
333
                                                vec2 <= '1';
334
                                        else
335
                                                vec4 <= '1';
336
                                        end if;
337
                                end if;
338
 
339
                        else
340
 
341
                                if rjmpm = '1' or rcallm = '1' or retm = '1' or retim = '1' then
342
                                        state <= nop2s;
343
                                elsif cbisbim = '1' then
344
                                        state <= cbisbis;
345
                                elsif sbicsm = '1' then
346
                                        state <= sbicss;
347
                                elsif ldm = '1' or ld_incm = '1' or ld_decm = '1' then
348
                                        state <= lds;
349
                                elsif stm = '1' or st_incm = '1' or st_decm = '1' then
350
                                        state <= sts;
351
                                elsif sleepm = '1' then
352
                                        state <= sleeps;
353
                                end if;
354
 
355
                                -- PC signals
356
                                jmp  <= rjmpm or rcallm; -- encoded
357
                                push <= rcallm;
358
                                pull <= retm or retim;
359
 
360
                                -- PC and IR signals
361
                                en <= not (cbisbim or sbicsm
362
                                                or stm or st_incm or st_decm or
363
                                                ldm or ld_incm or ld_decm);
364
 
365
                                -- General Purpose Register File signals
366
                                wr_reg <= addm or adcm or incm
367
                                                or subm or subim or sbcm or sbcim or decm or negm
368
                                                or andm or andim or orm or orim or eorm or comm
369
                                                or lsrm or rorm or asrm
370
                                                or ldim or movm or swapm
371
                                                or inm;
372
                                inc_zp <= ld_incm or st_incm;
373
                                dec_zp <= ld_decm or st_decm;
374
 
375
                                -- ALU signals
376
                                add <= addm or adcm or incm;
377
                                subcp <= subm or subim or sbcm or sbcim or decm or negm
378
                                                or cpm or cpim or cpcm;
379
                                logic <= andm or andim or orm or orim or eorm or comm;
380
                                right <= lsrm or rorm or asrm;
381
                                dir <= ldim or movm or swapm;
382
                                bld <= bldm;
383
                                pass_a <= outm or stm or st_incm or st_decm;
384
                                cpse <= cpsem;
385
                                skiptest <= sbrcsm;
386
 
387
 
388
 
389
                                -- SR signals
390
                                bclr <= bclrm;
391
                                bset <= bsetm;
392
                                set_i <= retim;
393
 
394
                                sren(0) <= addm or adcm
395
                                         or subm or subim or sbcm or sbcim or cpm or cpcm or cpim or negm
396
                                         or comm
397
                                         or lsrm or rorm or asrm;
398
 
399
                                for i in 1 to 4 loop
400
                                        sren(i) <= addm or adcm or incm
401
                                         or subm or subim or sbcm or sbcim or cpm or cpcm or cpim or decm or negm
402
                                         or andm or andim or orm or orim or eorm or comm
403
                                         or lsrm or rorm or asrm;
404
                                end loop;
405
 
406
                                sren(5) <= addm or adcm
407
                                         or subm or subim or sbcm or sbcim or cpm or cpcm or cpim or negm;
408
 
409
                                sren(6) <= bstm;
410
 
411
                                -- Data RAM signals
412
                                ld_mar <= ldm or ld_incm or ld_decm or stm or st_incm or st_decm;
413
                                ld_mbr <= stm or st_incm or st_decm;
414
 
415
                                -- I/O decoder signals
416
                                wr_io <= outm;
417
                                rd_io <= inm or sbicsm or cbisbim;
418
                                if inm = '1' or outm = '1' then
419
                                        ioaddr <= conv_integer(ir(10 downto 9) & ir(3 downto 0));
420
                                else
421
                                        ioaddr <= conv_integer('0' & ir(7 downto 3));
422
                                end if;
423
 
424
 
425
                                -- Branch Evaluation Unit signal
426
                                branchtest <= brbcsm;
427
 
428
 
429
                                -- Fetch I/O, generate C2A
430
                                get_io <= cbisbim or sbicsm;
431
 
432
                        end if;
433
 
434
                when nop2s =>
435
                        state <= nop1s;
436
 
437
                when nop1s =>
438
                        state <= exes;
439
 
440
                when cbisbis =>
441
                        state <= exes;
442
                        cbisbi <= '1';
443
                        wr_io <= '1';
444
 
445
                when sbicss =>
446
                        state <= exes;
447
                        skiptest <= '1';
448
 
449
                when lds =>
450
                        state <= exes;
451
                        wr_reg <= '1';
452
                        rd_ram <= '1';
453
 
454
                when sts =>
455
                        state <= exes;
456
                        wr_ram_fast <= '1';
457
 
458
                when sleeps =>
459
                        en <= '0';
460
                        if irq = '1' then
461
                                en <= '1';
462
                                state <= nop2s;
463
                                push <= '1';
464
                                if extirq = '1' then
465
                                        vec2 <= '1';
466
                                else
467
                                        vec4 <= '1';
468
                                end if;
469
                        end if;
470
 
471
        end case;
472
 
473
end if;
474
end process;
475
 
476
-- Generate Delayed WR_RAM signal to avoid writing to wrong address
477
process(state, wr_ram_fast)
478
begin
479
        if state = exes then
480
                wr_ram <= wr_ram_fast;
481
        else
482
                wr_ram <= '0';
483
        end if;
484
end process;
485
 
486
 
487
-- Branch Evaluation Unit
488
process(branchtest, sr, ibr)
489
begin
490
        if branchtest = '1' and (sr(conv_integer(ibr(2 downto 0))) = not ibr(10)) then
491
                branch <= '1';
492
        else
493
                branch <= '0';
494
        end if;
495
end process;
496
 
497
 
498
-- IO address decoder
499
iodec : v_iodecoder
500
        port map (ioaddr, rd_io, wr_io, rd_sreg, wr_sreg, rd_gimsk, wr_gimsk, rd_timsk, wr_timsk, rd_tifr, wr_tifr, rd_mcucr, wr_mcucr, rd_tccr0, wr_tccr0, rd_tcnt0, wr_tcnt0, rd_portb, wr_portb, rd_ddrb, wr_ddrb, rd_pinb, rd_portc, wr_portc, rd_ddrc, wr_ddrc, rd_pinc, rd_portd, wr_portd, rd_ddrd, wr_ddrd, rd_pind);
501
 
502
 
503
-- Intruction Buffer Register (IBR) to signals ------------------
504
dest <= conv_integer(ibr(7 downto 4));
505
srsel <= conv_integer(ibr(6 downto 4));
506
set <= ibr(9);
507
bitsel <= conv_integer(ibr(2 downto 0));
508
offset <=       ibr(8 downto 0) when jmp = '1' else
509
                        ibr(9) & ibr(9) & ibr(9 downto 3);
510
 
511
 
512
-- Generate Fetch Stage Signals : ASEL and SEL
513
imm <= subim or sbcim or cpim or andim or orim or ldim;
514
one <= incm or decm;
515
neg <= negm;
516
 
517
asel <= 1 when neg = '1' and get_io = '0' else
518
                0;
519
bsel <= 1 when neg = '1' else
520
                2 when imm = '1' else
521
                3 when one = '1' else
522
                0;
523
 
524
 
525
-- Decode Control Signal
526
addoffset <= branch or jmp; -- PC
527
clr_i <= vec2 or vec4; -- PC
528
clr_intf <= vec2; -- External Interrupt
529
clr_tov0 <= vec4; -- Timer
530
 
531
end controlunit;
532
 
533
 

powered by: WebSVN 2.1.0

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