proc_rtl.vhd
来自「Intel微处理器8088的VHDL实现」· VHDL 代码 · 共 950 行 · 第 1/5 页
VHD
950 行
if instr.xmod="11" then -- Register to Register rm=reg field
second_pass_s <= '0';
if (instr.ireg(1)='1') then -- Check 'd' bit, if 1 dest=reg else r/m
path_s.datareg_input<= ALUBUS_IN & instr.ireg(0) & instr.reg; -- dimux & w & seldreg Note REG=Destination!
-- Note aluopr = bit 5 to 3 of opcode
-- Note ALU_ADD(6 downto 4) is generic for all sub types
-- Note the selalua and selalub values are important for the SUB and CMP instructions!
-- It would have been nice if the position was fixed in the opcode!
path_s.alu_operation<= '0'&instr.reg & '0'&instr.rm & ALU_ADD(6 downto 4)&instr.ireg(7)&instr.ireg(5 downto 3);-- selalua & selalub & aluopr
else
path_s.datareg_input<= ALUBUS_IN & instr.ireg(0) & instr.rm; -- dimux & w & seldreg Note RM=Destination!
path_s.alu_operation<= '0'&instr.rm & '0'&instr.reg & ALU_ADD(6 downto 4)&instr.ireg(7)&instr.ireg(5 downto 3);-- selalua & selalub & aluopr
end if;
path_s.ea_output <= NB_CS_IP; -- IPREG+NB ADDR=CS:IP
--if (instr.ireg(7 downto 2)/="001110") then -- Check if not CMP or TEST Instruction
if ((instr.ireg(5 downto 3)/="111") and (instr.ireg(7)='0')) then -- Check if not CMP or TEST Instruction
wrpath_s.wrd <= '1'; -- Write Data Register to Data Register
end if;
wrpath_s.wrcc <= '1'; -- Update Status Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sexecute;
else -- Source/dest is memory
if instr.ireg(1)='0' then -- Check 'd' bit ->0 SRC=Reg, DEST=rm, Read & Write Cycle (mem<- mem, reg, AND)
path_s.datareg_input<= DONTCARE(2 downto 0) & instr.ireg(0) & DONTCARE(2 downto 0); -- dimux & w & seldreg (only w)
path_s.alu_operation<= REG_MDBUS & '0'&instr.reg & ALU_ADD(6 downto 4)&instr.ireg(7)&instr.ireg(5 downto 3); -- selalua & selalub & aluopr Path for ALU
path_s.dbus_output <= ALUBUS_OUT; --{eabus(0)&} domux setting
path_s.ea_output <= NB_DS_EA; -- dispmux & eamux & segop (unless Segment OP flag is set)
if (second_pass='0') then -- first pass read operand
second_pass_s <= '1'; -- need another pass
next_state <= Sreadmem; -- start read cycle
else
second_pass_s <= '0'; -- clear
wrpath_s.wrcc <= '1'; -- Update Status Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
if ((instr.ireg(5 downto 3)/="111") and (instr.ireg(7)='0')) then-- Check if not CMP or TEST Instruction
next_state <= Swritemem; -- start write cycle
else
next_state <= Sexecute;
end if;
end if;
else -- 'd'=1 SRC=rm, DEST=Reg, Read Cycle (reg<- reg, mem, AND)
second_pass_s <= '0';
-- Select Data for result path
path_s.datareg_input<= ALUBUS_IN & instr.ireg(0) & instr.reg; -- dimux & w & seldreg
-- Select Path for ALU
path_s.alu_operation<= '0'&instr.reg & REG_MDBUS & ALU_ADD(6 downto 4)&instr.ireg(7)&instr.ireg(5 downto 3);-- selalua & selalub & aluopr
path_s.ea_output <= NB_DS_EA; -- dispmux & eamux & segop (unless Segment OP flag is set)
if ((instr.ireg(5 downto 3)/="111") and (instr.ireg(7)='0')) then-- Check if not CMP or TEST Instruction
wrpath_s.wrd <= '1'; -- Write Data Register to Data Register
end if;
wrpath_s.wrcc <= '1'; -- Update Status Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sreadmem; -- start read cycle
end if;
end if;
---------------------------------------------------------------------------------
-- OPCODE 80,81,82,83, ADD/ADC/SUB/SBB/CMP/AND/OR/XOR Immediate to Reg/Mem
-- ALU operation is defined in reg field (3 bits) and not in bit 5-3 of opcode
-- Data is routed from drmux->dibus->dbusdp_out
-- If instr(1)=1 then signextend the data byte (SW=11)
---------------------------------------------------------------------------------
when O80I2RM | O81I2RM | O83I2RM =>
if instr.xmod="11" then -- Immediate to Register r/m=reg field
second_pass_s <= '0';
path_s.datareg_input<= ALUBUS_IN & instr.ireg(0) & instr.rm; -- dimux & w & seldreg Note RM=Destination!!
-- instr.reg contains the required operation (Reg AND Constant)
-- If s-bit=0 then 000+REG else 110+REG, s-bit is bit 1 of instr.reg
path_s.alu_operation<= '0'&instr.rm & REG_DATAIN &instr.ireg(1)&instr.ireg(1)&"00"&instr.reg; -- selalua & selalub & aluopr
path_s.ea_output <= NB_CS_IP; -- IPREG+NB ADDR=CS:IP
if (instr.reg/="111") then -- Check if not CMP Instruction
wrpath_s.wrd <= '1'; -- Write Data Register to Data Register
end if;
wrpath_s.wrcc <= '1'; -- Update Status Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sexecute;
else -- Destination and source is memory (no wrpath_s.wrd)
-- This is nearly the same as AND with d=0, see above
-- only need W bit
path_s.datareg_input<= DONTCARE(2 downto 0) & instr.ireg(0) & DONTCARE(2 downto 0); -- dimux & w & seldreg (only dimux, the rest is don't care)
-- Memory AND Constant, need to read memory first
path_s.alu_operation<= REG_MDBUS & REG_DATAIN&instr.ireg(1)&instr.ireg(1)&"00"&instr.reg; -- selalua & selalub & aluopr
path_s.dbus_output <= ALUBUS_OUT; --{eabus(0)&} domux setting
path_s.ea_output <= NB_DS_EA; -- dispmux & eamux & segop (unless Segment OP flag is set)
if (second_pass='0') then -- first pass read operand
second_pass_s <= '1'; -- need another pass
next_state <= Sreadmem; -- start read cycle
else
second_pass_s <= '0'; -- clear
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
wrpath_s.wrcc <= '1'; -- Update Status Register
if (instr.reg/="111") then -- Check if not CMP Instruction
next_state <= Swritemem; -- start write cycle
else
next_state <= Sexecute; -- CMP, do not write results
end if;
end if;
end if;
-----------------------------------------------------------------------------
-- NOT/TEST F6/F7 Shared Instructions
-- TEST regfield=000
-- NOT regfield=010
-- NEG regfield=011
-- MUL regfield=100
-- IMUL regfield=101
-- DIV regfield=110
-- IDIV regfield=111
-- ALU operation is defined in bits 5-3 of modrm.reg
-- Same sequence as OPC80..83 instruction?
-- Note for NOT instruction DATAIN must be zero!!
-----------------------------------------------------------------------------
when F6INSTR | F7INSTR =>
-- case instr.reg(2 downto 0) is
case instr.reg is
when "000" => -- TEST instruction, Combine with NEG/NOT Instruction ?????????????
if instr.xmod="11" then -- Immediate to Register r/m=reg field
second_pass_s <= '0';
path_s.datareg_input<= ALUBUS_IN & instr.ireg(0) & instr.rm; -- dimux & w & seldreg
-- instr.reg contains the required operation
-- Note ALU_TEST2 is generic for all sub types
path_s.alu_operation<= '0'&instr.rm & REG_DATAIN & ALU_TEST2(6 downto 3)&instr.reg; -- selalua & selalub & aluopr
path_s.ea_output <= NB_CS_IP; -- IPREG+NB ADDR=CS:IP
wrpath_s.wrcc <= '1'; -- Update Status Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sexecute;
else -- Destination and source is memory (no wrpath_s.wrd)
-- This is nearly the same as AND with d=0, see above
-- only need W bit
path_s.datareg_input<= DONTCARE(2 downto 0) & instr.ireg(0) & DONTCARE(2 downto 0); -- dimux & w & seldreg (only dimux, the rest is don't care)
-- Memory AND Constant, need to read memory first
path_s.alu_operation<= REG_MDBUS & REG_DATAIN & ALU_TEST2(6 downto 3)&instr.reg; -- selalua & selalub & aluopr
path_s.dbus_output <= ALUBUS_OUT; --{eabus(0)&} domux setting
path_s.ea_output <= NB_DS_EA; -- dispmux & eamux & segop (unless Segment OP flag is set)
if (second_pass='0') then -- first pass read operand
second_pass_s <= '1'; -- need another pass
next_state <= Sreadmem; -- start read cycle
else
second_pass_s <= '0'; -- clear
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
wrpath_s.wrcc <= '1'; -- Update Status Register
next_state <= Sexecute; -- TEST, do not write results
end if;
end if;
when "010" | "011" => -- Invert NOT and 2s complement NEG
-- Check with others to see if can be combined!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if instr.xmod="11" then -- Negate Register r/m=reg field
second_pass_s <= '0';
path_s.datareg_input<= ALUBUS_IN & instr.ireg(0) & instr.rm; -- dimux & w & seldreg
-- Note ALU_TEST2 is generic for all sub types
if (instr.reg(0)='1') then -- NEG instruction
path_s.alu_operation<= '0'&instr.rm & REG_CONST1 & ALU_TEST2(6 downto 3)&instr.reg; -- selalua & se
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?