proc_rtl.vhd
来自「Intel微处理器8088的VHDL实现」· VHDL 代码 · 共 950 行 · 第 1/5 页
VHD
950 行
wrpath_s.wrs <= '1'; -- Write Data Register to Segment Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sexecute;
else -- Memory to Segment Register
path_s.segreg_input <= SMDBUS_IN & instr.reg(1 downto 0); -- simux & selsreg
path_s.ea_output <= NB_DS_EA; -- dispmux & eamux & segop (unless Segment OP flag is set)
wrpath_s.wrs <= '1'; -- Write Memory to Segment Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sreadmem; -- start read cycle
end if;
---------------------------------------------------------------------------------
-- Load Effective Address in Data Register
-- mod=11 result in proc_error
---------------------------------------------------------------------------------
when LEA =>
second_pass_s <= '0';
if instr.xmod="11" then -- Register to Register rm=reg field
proc_error_s<='1'; -- Assert Bus Error Signal
-- pragma synthesis_off
assert not (now > 0 ns) report "**** Illegal LEA operand (mod=11) (proc) ***" severity failure;
-- pragma synthesis_on
end if; -- Transfer Effective addresss (EABUS) to data register
path_s.datareg_input<= EABUS_IN & '1' & instr.reg; -- dimux & w & seldreg
path_s.ea_output <= NB_DS_EA; -- dispmux & eamux & segop
wrpath_s.wrd <= '1'; -- Write EABUS to Data Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sexecute;
---------------------------------------------------------------------------------
-- Load Effective Address in ES/DS:DEST_REGISTER
-- mod=11 result in proc_error
-- TEMP <= readmem(ea) ; PASS1 (required for cases like LES SI,[SI] )
-- REG <= TEMP ; PASS2
-- ES/DS<= readmem(ea+2)
---------------------------------------------------------------------------------
when LES | LDS =>
if instr.xmod="11" then -- Register to Register rm=reg field
proc_error_s<='1'; -- Assert Bus Error Signal
-- pragma synthesis_off
assert not (now > 0 ns) report "**** Illegal LES/LDS operand (mod=11) (proc) ***" severity warning;
-- pragma synthesis_on
end if;
path_s.alu_operation<= DONTCARE(3 downto 0) & REG_MDBUS & ALU_TEMP;-- selalua(4) & selalub(4) & aluopr
if (second_pass='0') then -- first pass reg<=mem(ea)
second_pass_s <= '1'; -- need another pass
path_s.datareg_input<= MDBUS_IN & '1' & instr.reg;-- dimux & w & seldreg
path_s.ea_output<="0000001001"; -- dispmux(3) & eamux(4)=EA & dis_opflag & segop[1:0]
wrpath_s.wrtemp <= '1'; -- Write reg value to alu_temp first
next_state <= Sreadmem; -- start read to read temp<=EA
else
second_pass_s <= '0'; -- clear
path_s.datareg_input<= ALUBUS_IN & '1' & instr.reg;-- dimux & w & seldreg
path_s.ea_output<="0000011001"; -- dispmux(3) & eamux(4)=EA+2 & dis_opflag & segop[1:0]
-- Second Pass ES/DS<=mem(ea+2)
if instr.ireg(0)='0' then -- C4=LES
path_s.segreg_input <= SMDBUS_IN & ES_IN(1 downto 0); -- simux & selsreg=ES
else -- C5=LDS
path_s.segreg_input <= SMDBUS_IN & DS_IN(1 downto 0); -- simux & selsreg=DS
end if;
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
wrpath_s.wrd <= '1'; -- Update Reg<=temp
wrpath_s.wrs <= '1'; -- Update ES/DS Register
next_state <= Sreadmem;
end if;
---------------------------------------------------------------------------------
-- Convert AL to AX, AX -> DX:AX
-- Flags are not affected
---------------------------------------------------------------------------------
when CBW | CWD =>
second_pass_s <= '0';
-- Note ALU_SEXT(6 downto 4) is generic for CBW and CWD
path_s.alu_operation<= REG_AX & DONTCARE(3 downto 0) & ALU_SEXT(6 downto 4) & instr.ireg(3 downto 0) ;-- selalua & selalub & aluopr
if (instr.ireg(0)='0') then -- if 0 then CBW else CWD
path_s.datareg_input<= ALUBUS_IN & '1' & REG_AX(2 downto 0);-- dimux & w & seldreg Note RM=Destination!!
else
path_s.datareg_input<= ALUBUS_IN & '1' & REG_DX(2 downto 0);-- dimux & w & seldreg Note RM=Destination!!
end if;
path_s.ea_output <= NB_CS_IP; -- IPREG+NB ADDR=CS:IP
wrpath_s.wrd <= '1'; -- Write Data Register to Data Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sexecute;
---------------------------------------------------------------------------------
-- Convert AL
-- Use bit 4 of instruction to drive W bit
---------------------------------------------------------------------------------
when AAS | DAS | AAA | DAA | AAM | AAD =>
passcnt_s <= passcnt - '1';
path_s.ea_output <= NB_CS_IP; -- IPREG+NB ADDR=CS:IP
path_s.datareg_input<= ALUBUS_IN & instr.ireg(4) & REG_AX(2 downto 0);-- dimux & w & seldreg Note RM=Destination!!
path_s.alu_operation<= REG_AX & DONTCARE(3 downto 0) & ALU_DAA(6 downto 4)&instr.ireg(0)&instr.ireg(5 downto 3);-- selalua & selalub & aluopr
if (second_pass='0') then -- first pass
if (instr.ireg=AAM) then -- AAM instruction only
second_pass_s <= '1'; -- need another pass
wrpath_s.wralu <= '1'; -- Write Data to ALUREG, only used for AAM (uses divider)
passcnt_s <= DIV_MCD_C; -- Serial delay
next_state <= Sdecode; -- round the loop again
else
second_pass_s <= '0';
wrpath_s.wrcc <= '1'; -- Update Status Register
wrpath_s.wrd <= '1'; -- Write Data Register to Data Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sexecute; -- terminate
end if;
else
second_pass_s <= '1';
if (passcnt="000000") then -- Divider Done?
second_pass_s <= '0';
wrpath_s.wrcc <= '1'; -- Update Status Register
wrpath_s.wrd <= '1'; -- Write Data Register to Data Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sexecute; -- terminate
end if;
end if;
---------------------------------------------------------------------------------
-- Segment Override Prefix
---------------------------------------------------------------------------------
when SEGOPES | SEGOPCS | SEGOPSS | SEGOPDS =>
irq_blocked_s <= '1'; -- Block IRQ if asserted during next instr.
second_pass_s <= '0';
path_s.datareg_input<= DONTCARE(2 downto 0) & instr.ireg(0) & DONTCARE(2 downto 0); -- dimux & w & seldreg
path_s.ea_output <= "000"&DONTCARE(3 downto 0) & '0' & instr.ireg(4 downto 3); -- dispmux & eamux(4) & [flag]&segop[1:0]
wrpath_s.wrop <= '1'; -- Write to Override Prefix Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sexecute;
---------------------------------------------------------------------------------
-- LOCK Prefix, Not implemented, result in NOP
---------------------------------------------------------------------------------
when LOCKBUS =>
-- irq_blocked_s <= '1'; -- Block IRQ if asserted during next instr.
second_pass_s <= '0';
path_s.ea_output<= NB_CS_IP;
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sexecute;
---------------------------------------------------------------------------------
-- Halt Instruction, wait for NMI, INTR, Reset
---------------------------------------------------------------------------------
when HLT =>
second_pass_s <= '0';
path_s.ea_output<= NB_CS_IP;
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sexecute;
---------------------------------------------------------------------------------
-- ADD/ADC/SUB/SBB/CMP/AND/OR/XOR Register/Memory <- Register/Memory
-- TEST same as AND without returning any result (wrpath_s.wrd is not asserted)
---------------------------------------------------------------------------------
when ADDRM2R0 | ADDRM2R1 | ADDRM2R2 | ADDRM2R3 | ADCRM2R0 | ADCRM2R1 | ADCRM2R2 | ADCRM2R3 |
SUBRM2R0 | SUBRM2R1 | SUBRM2R2 | SUBRM2R3 | SBBRM2R0 | SBBRM2R1 | SBBRM2R2 | SBBRM2R3 |
CMPRM2R0 | CMPRM2R1 | CMPRM2R2 | CMPRM2R3 | ANDRM2R0 | ANDRM2R1 | ANDRM2R2 | ANDRM2R3 |
ORRM2R0 | ORRM2R1 | ORRM2R2 | ORRM2R3 | XORRM2R0 | XORRM2R1 | XORRM2R2 | XORRM2R3 |
TESTRMR0 | TESTRMR1 =>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?