📄 v_controlunit.vhd
字号:
if rorm = '1' then rightsel <= 1;
elsif asrm = '1' then rightsel <= 2;
else rightsel <= 0;
end if;
if swapm = '1' then dirsel <= 1;
else dirsel <= 0;
end if;
end if;
end process;
-- Finite State Machine
irq <= (timerirq or extirq) and sr(7);
break <= branch or skip or irq;
process(clk, clrn)
begin
if clrn = '0' then
state <= exes;
en <= '1'; get_io <= '0';
pass_a <= '0'; wr_reg <= '0'; sren <= "0000000";
rd_io <= '0'; wr_io <= '0'; rd_ram <= '0'; wr_ram_fast <= '0';
ld_mar <= '0'; ld_mbr <= '0'; inc_zp <= '0'; dec_zp <= '0';
add <= '0'; subcp <= '0'; logic <= '0'; right <= '0'; dir <= '0';
jmp <= '0'; push <= '0'; pull <= '0'; branchtest <= '0';
bclr <= '0'; bset <= '0'; bld <= '0';
cpse <= '0'; skiptest <= '0';
cbisbi <= '0';
vec2 <= '0'; vec4 <= '0'; set_i <= '0';
elsif clk'event and clk = '1' then
en <= '1'; get_io <= '0';
pass_a <= '0'; wr_reg <= '0'; sren <= "0000000";
rd_io <= '0'; wr_io <= '0'; rd_ram <= '0'; wr_ram_fast <= '0';
ld_mar <= '0'; ld_mbr <= '0'; inc_zp <= '0'; dec_zp <= '0';
add <= '0'; subcp <= '0'; logic <= '0'; right <= '0'; dir <= '0';
jmp <= '0'; push <= '0'; pull <= '0'; branchtest <= '0';
bclr <= '0'; bset <= '0'; bld <= '0';
cpse <= '0'; skiptest <= '0';
cbisbi <= '0';
vec2 <= '0'; vec4 <= '0'; set_i <= '0';
case state is
when exes =>
if break = '1' then
if branch = '1' then
state <= nop1s;
elsif skip = '1' then
elsif irq = '1' then
state <= nop2s;
push <= '1';
if extirq = '1' then
vec2 <= '1';
else
vec4 <= '1';
end if;
end if;
else
if rjmpm = '1' or rcallm = '1' or retm = '1' or retim = '1' then
state <= nop2s;
elsif cbisbim = '1' then
state <= cbisbis;
elsif sbicsm = '1' then
state <= sbicss;
elsif ldm = '1' or ld_incm = '1' or ld_decm = '1' then
state <= lds;
elsif stm = '1' or st_incm = '1' or st_decm = '1' then
state <= sts;
elsif sleepm = '1' then
state <= sleeps;
end if;
-- PC signals
jmp <= rjmpm or rcallm; -- encoded
push <= rcallm;
pull <= retm or retim;
-- PC and IR signals
en <= not (cbisbim or sbicsm
or stm or st_incm or st_decm or
ldm or ld_incm or ld_decm);
-- General Purpose Register File signals
wr_reg <= addm or adcm or incm
or subm or subim or sbcm or sbcim or decm or negm
or andm or andim or orm or orim or eorm or comm
or lsrm or rorm or asrm
or ldim or movm or swapm
or inm;
inc_zp <= ld_incm or st_incm;
dec_zp <= ld_decm or st_decm;
-- ALU signals
add <= addm or adcm or incm;
subcp <= subm or subim or sbcm or sbcim or decm or negm
or cpm or cpim or cpcm;
logic <= andm or andim or orm or orim or eorm or comm;
right <= lsrm or rorm or asrm;
dir <= ldim or movm or swapm;
bld <= bldm;
pass_a <= outm or stm or st_incm or st_decm;
cpse <= cpsem;
skiptest <= sbrcsm;
-- SR signals
bclr <= bclrm;
bset <= bsetm;
set_i <= retim;
sren(0) <= addm or adcm
or subm or subim or sbcm or sbcim or cpm or cpcm or cpim or negm
or comm
or lsrm or rorm or asrm;
for i in 1 to 4 loop
sren(i) <= addm or adcm or incm
or subm or subim or sbcm or sbcim or cpm or cpcm or cpim or decm or negm
or andm or andim or orm or orim or eorm or comm
or lsrm or rorm or asrm;
end loop;
sren(5) <= addm or adcm
or subm or subim or sbcm or sbcim or cpm or cpcm or cpim or negm;
sren(6) <= bstm;
-- Data RAM signals
ld_mar <= ldm or ld_incm or ld_decm or stm or st_incm or st_decm;
ld_mbr <= stm or st_incm or st_decm;
-- I/O decoder signals
wr_io <= outm;
rd_io <= inm or sbicsm or cbisbim;
if inm = '1' or outm = '1' then
ioaddr <= conv_integer(ir(10 downto 9) & ir(3 downto 0));
else
ioaddr <= conv_integer('0' & ir(7 downto 3));
end if;
-- Branch Evaluation Unit signal
branchtest <= brbcsm;
-- Fetch I/O, generate C2A
get_io <= cbisbim or sbicsm;
end if;
when nop2s =>
state <= nop1s;
when nop1s =>
state <= exes;
when cbisbis =>
state <= exes;
cbisbi <= '1';
wr_io <= '1';
when sbicss =>
state <= exes;
skiptest <= '1';
when lds =>
state <= exes;
wr_reg <= '1';
rd_ram <= '1';
when sts =>
state <= exes;
wr_ram_fast <= '1';
when sleeps =>
en <= '0';
if irq = '1' then
en <= '1';
state <= nop2s;
push <= '1';
if extirq = '1' then
vec2 <= '1';
else
vec4 <= '1';
end if;
end if;
end case;
end if;
end process;
-- Generate Delayed WR_RAM signal to avoid writing to wrong address
process(state, wr_ram_fast)
begin
if state = exes then
wr_ram <= wr_ram_fast;
else
wr_ram <= '0';
end if;
end process;
-- Branch Evaluation Unit
process(branchtest, sr, ibr)
begin
if branchtest = '1' and (sr(conv_integer(ibr(2 downto 0))) = not ibr(10)) then
branch <= '1';
else
branch <= '0';
end if;
end process;
-- IO address decoder
iodec : v_iodecoder
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);
-- Intruction Buffer Register (IBR) to signals ------------------
dest <= conv_integer(ibr(7 downto 4));
srsel <= conv_integer(ibr(6 downto 4));
set <= ibr(9);
bitsel <= conv_integer(ibr(2 downto 0));
offset <= ibr(8 downto 0) when jmp = '1' else
ibr(9) & ibr(9) & ibr(9 downto 3);
-- Generate Fetch Stage Signals : ASEL and SEL
imm <= subim or sbcim or cpim or andim or orim or ldim;
one <= incm or decm;
neg <= negm;
asel <= 1 when neg = '1' and get_io = '0' else
0;
bsel <= 1 when neg = '1' else
2 when imm = '1' else
3 when one = '1' else
0;
-- Decode Control Signal
addoffset <= branch or jmp; -- PC
clr_i <= vec2 or vec4; -- PC
clr_intf <= vec2; -- External Interrupt
clr_tov0 <= vec4; -- Timer
end controlunit;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -