📄 alu.vhd
字号:
end case;
-------------------------------
-- PSW(2) OV FLAG WRITE
-------------------------------
case instr is
when
ADD_IR0 | ADD_IR1 |
ADD_R0 | ADD_R1 |
ADD_R2 | ADD_R3 |
ADD_R4 | ADD_R5 |
ADD_R6 | ADD_R7 |
ADDC_IR0 | ADDC_IR1 |
ADDC_R0 | ADDC_R1 |
ADDC_R2 | ADDC_R3 |
ADDC_R4 | ADDC_R5 |
ADDC_R6 | ADDC_R7 |
SUBB_IR0 | SUBB_IR1 |
SUBB_R0 | SUBB_R1 |
SUBB_R2 | SUBB_R3 |
SUBB_R4 | SUBB_R5 |
SUBB_R6 | SUBB_R7 |
ADD_N | ADD_ADDR |
ADDC_N | ADDC_ADDR |
SUBB_N | SUBB_ADDR =>
if (cycle=2 and phase=6) then
psw(2) <= ov_bit;
end if;
when
MUL_AB =>
psw(2) <= mul_ov_bit;
when
DIV_AB =>
if cycle = 1 then
if b="00000000" then
psw(2) <= '1';
else
psw(2) <= '0';
end if;
end if;
when others =>
null;
end case;
-------------------------------
-- PSW(0) P FLAG WRITE
-------------------------------
psw(0) <= parity_flag;
end if;
end if;
end if;
end process;
--------------------------------------------------------------------
-- Parity bit driver
--------------------------------------------------------------------
parity_flag_hand :
-------------------------------------------------------------------
parity_flag <=
(acc(0) xor
acc(1) xor
acc(2) xor
acc(3) xor
acc(4) xor
acc(5) xor
acc(6) xor
acc(7));
--------------------------------------------------------------------
-- ALU arithmetic operations
--------------------------------------------------------------------
combinational_b1_alu_proc:
--------------------------------------------------------------------
process(instr, a1, a2, op_c)
variable res_3_0 : STD_LOGIC_VECTOR(4 downto 0);
variable res_6_4 : STD_LOGIC_VECTOR(3 downto 0);
variable res_8_7 : STD_LOGIC_VECTOR(1 downto 0);
begin
case instr is
when
ADD_N | ADD_ADDR | ADD_IR0 | ADD_IR1 |
ADD_R0 | ADD_R1 | ADD_R2 | ADD_R3 |
ADD_R4 | ADD_R5 | ADD_R6 | ADD_R7 =>
res_3_0 := '0'&a1(3 downto 0)+a2(3 downto 0);
res_6_4 := '0'&a1(6 downto 4)+a2(6 downto 4)+res_3_0(4);
res_8_7 := '0'&a1(7) + a2(7) + res_6_4(3);
result_b1 <= res_8_7&res_6_4(2 downto 0)&
res_3_0(3 downto 0);
when
ADDC_N | ADDC_ADDR | ADDC_IR0 | ADDC_IR1 |
ADDC_R0 | ADDC_R1 | ADDC_R2 | ADDC_R3 |
ADDC_R4 | ADDC_R5 | ADDC_R6 | ADDC_R7 =>
res_3_0 := '0'&a1(3 downto 0)+a2(3 downto 0)+op_c;
res_6_4 := '0'&a1(6 downto 4)+a2(6 downto 4)+res_3_0(4);
res_8_7 := '0'&a1(7) + a2(7) + res_6_4(3);
result_b1 <= res_8_7&res_6_4(2 downto 0)&
res_3_0(3 downto 0);
when
SUBB_N | SUBB_ADDR | SUBB_IR0 | SUBB_IR1 |
SUBB_R0 | SUBB_R1 | SUBB_R2 | SUBB_R3 |
SUBB_R4 | SUBB_R5 | SUBB_R6 | SUBB_R7 =>
res_3_0 := '0'&a1(3 downto 0)-a2(3 downto 0)-op_c;
res_6_4 := '0'&a1(6 downto 4)-a2(6 downto 4)-res_3_0(4);
res_8_7 := '0'&a1(7) - a2(7) - res_6_4(3);
result_b1 <= res_8_7&res_6_4(2 downto 0)&
res_3_0(3 downto 0);
when
CJNE_A_N | CJNE_A_ADDR | CJNE_IR0_N | CJNE_IR1_N |
CJNE_R0_N | CJNE_R1_N | CJNE_R2_N | CJNE_R3_N |
CJNE_R4_N | CJNE_R5_N | CJNE_R6_N | CJNE_R7_N =>
res_3_0 := '0'&a1(3 downto 0)-a2(3 downto 0);
res_6_4 := '0'&a1(6 downto 4)-a2(6 downto 4)-res_3_0(4);
res_8_7 := '0'&a1(7) - a2(7) - res_6_4(3);
result_b1 <= res_8_7&res_6_4(2 downto 0)&
res_3_0(3 downto 0);
when
INC_A | INC_ADDR | INC_IR0 | INC_IR1 |
INC_R0 | INC_R1 | INC_R2 | INC_R3 |
INC_R4 | INC_R5 | INC_R6 | INC_R7 =>
res_3_0 := "-----";
res_6_4 := "----";
res_8_7 := "--";
result_b1 <= '0' & a2 + '1';
when
DEC_A | DEC_ADDR | DEC_IR0 | DEC_IR1 |
DEC_R0 | DEC_R1 | DEC_R2 | DEC_R3 |
DEC_R4 | DEC_R5 | DEC_R6 | DEC_R7 |
DJNZ_R0 | DJNZ_R1 | DJNZ_R2 | DJNZ_R3 |
DJNZ_R4 | DJNZ_R5 | DJNZ_R6 | DJNZ_R7 |
DJNZ_ADDR =>
res_3_0 := "-----";
res_6_4 := "----";
res_8_7 := "--";
result_b1 <= '0' & a2 - '1';
when others =>
res_3_0 := "-----";
res_6_4 := "----";
res_8_7 := "--";
result_b1 <= "---------";
end case;
ac_flag <= res_3_0(4);
ov_flag <= (res_6_4(3) xor res_8_7(1));
end process;
--------------------------------------------------------------------
-- ALU logical operations
--------------------------------------------------------------------
combinational_b2_alu_proc:
--------------------------------------------------------------------
process(instr, a1, a2, psw)
variable res_3_0 : STD_LOGIC_VECTOR(4 downto 0);
variable res_6_4 : STD_LOGIC_VECTOR(3 downto 0);
variable res_8_7 : STD_LOGIC_VECTOR(1 downto 0);
begin
case instr is
when
ORL_ADDR_A | ORL_ADDR_N | ORL_A_N | ORL_A_ADDR |
ORL_A_IR0 | ORL_A_IR1 | ORL_A_R0 | ORL_A_R1 |
ORL_A_R2 | ORL_A_R3 | ORL_A_R4 | ORL_A_R5 |
ORL_A_R6 | ORL_A_R7 =>
res_3_0 := "-----";
res_6_4 := "----";
res_8_7 := "--";
result_b2 <='0' & (a1 or a2);
when
XRL_ADDR_A | XRL_ADDR_N | XRL_A_N | XRL_A_ADDR |
XRL_A_IR0 | XRL_A_IR1 | XRL_A_R0 | XRL_A_R1 |
XRL_A_R2 | XRL_A_R3 | XRL_A_R4 | XRL_A_R5 |
XRL_A_R6 | XRL_A_R7 =>
res_3_0 := "-----";
res_6_4 := "----";
res_8_7 := "--";
result_b2 <='0' & (a1 xor a2);
when
ANL_ADDR_A | ANL_ADDR_N | ANL_A_N | ANL_A_ADDR |
ANL_A_IR0 | ANL_A_IR1 | ANL_A_R0 | ANL_A_R1 |
ANL_A_R2 | ANL_A_R3 | ANL_A_R4 | ANL_A_R5 |
ANL_A_R6 | ANL_A_R7 =>
res_3_0 := "-----";
res_6_4 := "----";
res_8_7 := "--";
result_b2 <='0' & (a1 and a2);
when
DA_A =>
if (a2(3 downto 0)>"1001" or
psw(6)='1')
then
res_3_0 := '0'&a2(3 downto 0) + "0110";
res_6_4 := '0'&a2(6 downto 4) + res_3_0(4);
res_8_7 := '0'&a2(7) + res_6_4(3);
else
res_3_0 := '0'&a2(3 downto 0);
res_6_4 := '0'&a2(6 downto 4);
res_8_7 := '0'&a2(7);
end if;
if (res_8_7(0)&res_6_4(2 downto 0)>"1001" or
psw(7)='1' or
res_8_7(1)='1')
then
res_6_4 := '0'&res_6_4(2 downto 0) + "110";
res_8_7 := res_8_7 + res_6_4(3);
else
res_6_4 := '0'&res_6_4(2 downto 0);
--res_8_7 := res_8_7;
end if;
result_b2 <= res_8_7&res_6_4(2 downto 0)&
res_3_0(3 downto 0);
when
CLR_A =>
res_3_0 := "-----";
res_6_4 := "----";
res_8_7 := "--";
result_b2 <= "000000000";
when
CPL_A =>
res_3_0 := "-----";
res_6_4 := "----";
res_8_7 := "--";
result_b2 <= '-' & (not a1);
when
RL_A =>
res_3_0 := "-----";
res_6_4 := "----";
res_8_7 := "--";
result_b2 <= '-' & a1(6 downto 0) & a1(7);
when
RR_A =>
res_3_0 := "-----";
res_6_4 := "----";
res_8_7 := "--";
result_b2 <= '-' & a1(0) & a1(7 downto 1);
when
RLC_A =>
res_3_0 := "-----";
res_6_4 := "----";
res_8_7 := "--";
result_b2 <= a1(7 downto 0) & psw(7);
when
RRC_A =>
res_3_0 := "-----";
res_6_4 := "----";
res_8_7 := "--";
result_b2 <= a1(0) & psw(7) & a1(7 downto 1);
when
SWAP_A =>
res_3_0 := "-----";
res_6_4 := "----";
res_8_7 := "--";
result_b2 <= '-' & a1(3 downto 0) & a1(7 downto 4);
when others =>
res_3_0 := "-----";
res_6_4 := "----";
res_8_7 := "--";
result_b2 <= "---------";
end case;
end process;
--------------------------------------------------------------------
-- PSW flags write
--------------------------------------------------------------------
flags_write_proc:
--------------------------------------------------------------------
process (clk)
begin
if clk'event and clk='1' then
-------------------------------------
-- Synchronous reset
-------------------------------------
if rst = '1' then
cy_bit <= '0';
ac_bit <= '0';
ov_bit <= '0';
else
-------------------------------------
-- Synchronous write
-------------------------------------
case instr is
when
ADD_N | ADD_ADDR | ADD_IR0 | ADD_IR1 |
ADD_R0 | ADD_R1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -