proc_rtl.vhd
来自「Intel微处理器8088的VHDL实现」· VHDL 代码 · 共 950 行 · 第 1/5 页
VHD
950 行
end if;
-- Load memory into ALUREG
path_s.alu_operation<= DONTCARE(3 downto 0) & REG_MDBUS & ALU_REGL; -- selalua(4) & selalub(4) & aluopr(7)
wrpath_s.wralu <= '1'; -- ver 0.69, write MDBUS to ALUREG
if (instr.ireg(1)='1') then
passcnt_s <= status.cl5; -- Load CL loop counter
end if; -- else passcnt_s=1;
else -- second pass, MDBUS contains memory byte
-- selalua & selalu are dontcare
-- ALU_ROL(6 downto 4) is generic for all shift/rotate
path_s.alu_operation<= DONTCARE(3 downto 0) & '0'&instr.rm & ALU_ROL(6 downto 4)& instr.ireg(1) & instr.reg; -- selalua(4) & selalub(4) & aluopr(7)
wrpath_s.wrcc <= '1'; -- Update Status Register after each shift/rot
--if (passcnt="00001") then -- Check if end of shift/rotate
if (passcnt="00000") then -- ver 0.69, Check if end of shift/rotate
second_pass_s <= '0'; -- clear
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Swritemem; -- write result to memory & terminate
else
passcnt_s <= passcnt - '1';
second_pass_s <= '1';
wrpath_s.wralu<= '1'; -- Update ALUREG
next_state <= Sdecode; -- round the loop again
end if;
end if;
end if;
---------------------------------------------------------------------------------
-- Immediate to Register
---------------------------------------------------------------------------------
when MOVI2R0 | MOVI2R1 |MOVI2R2 |MOVI2R3 |MOVI2R4 | MOVI2R5 | MOVI2R6 | MOVI2R7 |
MOVI2R8 | MOVI2R9 |MOVI2R10|MOVI2R11|MOVI2R12| MOVI2R13| MOVI2R14| MOVI2R15 =>
second_pass_s <= '0';
path_s.datareg_input<= DATAIN_IN & instr.ireg(3) & instr.reg; -- dimux & w & seldreg
path_s.ea_output <= NB_CS_IP; -- IPREG+NB ADDR=CS:IP
wrpath_s.wrd <= '1'; -- Write to Data Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sexecute;
---------------------------------------------------------------------------------
-- Immediate to Register/Memory 0xC6, 0xC7
-- Data is routed from drmux->dibus->dbusdp_out
---------------------------------------------------------------------------------
when MOVI2RM0 | MOVI2RM1 =>
second_pass_s <= '0';
path_s.datareg_input<= DATAIN_IN & instr.ireg(0) & DONTCARE(2 downto 0); -- dimux & w & seldreg (only dimux, the rest is don't care)
-- change to instr.ireg(0) & instr.reg ???
path_s.dbus_output <= DIBUS_OUT; --{eabus(0)&} domux setting
path_s.ea_output <= NB_DS_EA; -- dispmux & eamux & segop (unless Segment OP flag is set)
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Swritemem; -- start write cycle
---------------------------------------------------------------------------------
-- Memory to Accu and Accu to Memory AL, AX, not AH! 0xA0..0xA3
-- Use fake xmod and rm setting
-- Use instruction but (4..3)=000 as register selector
---------------------------------------------------------------------------------
when MOVM2A0 | MOVM2A1 | MOVA2M0 | MOVA2M1 =>
second_pass_s <= '0';
path_s.datareg_input<= MDBUS_IN & instr.ireg(0) & instr.reg; -- dimux & w & seldreg (don't care for write cycle)
path_s.alu_operation<= '0'&instr.reg & DONTCARE(3 downto 0) & ALU_PASSA; -- selalua & selalub & aluopr (don't care for read cycle)
path_s.dbus_output <= ALUBUS_OUT; --{eabus(0)&} domux setting (don't care for read cycle)
path_s.ea_output <= NB_DS_EA; -- dispmux & eamux & segop (unless Segment OP flag is set)
if instr.ireg(1)='0' then -- 0= memory to Accu, Read Cycle
wrpath_s.wrd <= '1'; -- Write Memory to Data Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sreadmem; -- start read cycle
else -- 1=Accu to Memory, Write cycle
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Swritemem; -- start write cycle
end if;
---------------------------------------------------------------------------------
-- Move Register/Memory to/from Register 0x88..0x8B
---------------------------------------------------------------------------------
when MOVRM2R0 | MOVRM2R1 | MOVRM2R2 | MOVRM2R3 =>
second_pass_s <= '0';
if instr.xmod="11" then -- Register to Register rm=reg field
if instr.ireg(1)='0' then -- Check 'd' bit, 0-> SRC=Reg, DEST=rm
path_s.datareg_input<= ALUBUS_IN & instr.ireg(0) & instr.rm; -- dimux & w & seldreg
path_s.alu_operation<= '0'&instr.reg & DONTCARE(3 downto 0) & ALU_PASSA; -- selalua & selalub & aluopr
else -- 'd'=1 SRC=rm, DEST=Reg
path_s.datareg_input<= ALUBUS_IN & instr.ireg(0) & instr.reg; -- dimux & w & seldreg
path_s.alu_operation<= '0'&instr.rm & DONTCARE(3 downto 0) & ALU_PASSA; -- selalua & selalub & aluopr
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;
else -- Source is memory
if instr.ireg(1)='0' then -- Check 'd' bit, 0-> SRC=Reg, DEST=rm, Write Cycle
path_s.alu_operation<= '0'&instr.reg & DONTCARE(3 downto 0) & ALU_PASSA; -- selalua & selalub & aluopr
path_s.dbus_output <= ALUBUS_OUT; --{eabus(0)&} domux setting
path_s.datareg_input<= DONTCARE(2 downto 0) & instr.ireg(0) & DONTCARE(2 downto 0); -- dimux & w & seldreg
-- (only need w, the reset don't care)
path_s.ea_output <= NB_DS_EA; -- dispmux & eamux & segop (unless Segment OP flag is set)
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Swritemem; -- start write cycle
else -- 'd'=1 SRC=rm, DEST=Reg, Read Cycle
path_s.datareg_input<= MDBUS_IN & instr.ireg(0) & instr.reg; -- dimux & w & seldreg
path_s.alu_operation<= '0'&instr.rm & DONTCARE(3 downto 0) & ALU_PASSA; -- selalua & selalub & aluopr
path_s.ea_output <= NB_DS_EA; -- dispmux & eamux & segop (unless Segment OP flag is set)
wrpath_s.wrd <= '1'; -- Write Memory to Data Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sreadmem; -- start read cycle
end if;
end if;
---------------------------------------------------------------------------------
-- Move Segment register to data register or memory
---------------------------------------------------------------------------------
when MOVS2RM =>
second_pass_s <= '0';
if instr.xmod="11" then -- Segment Register to Data Register , rm=reg field
path_s.datareg_input<= '1'& instr.reg(1 downto 0) & '1' & instr.rm; -- dimux & w & seldreg
path_s.ea_output <= NB_CS_IP; -- IPREG+NB ADDR=CS:IP
wrpath_s.wrd <= '1'; -- Write Seg to Data Register
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Sexecute;
else -- Segment Register to memory indexed by rm
path_s.datareg_input<= '1'& instr.reg(1 downto 0) & '1' & DONTCARE(2 downto 0); -- dimux only -- [dimux(3) & w & seldreg(3)]
path_s.dbus_output <= DIBUS_OUT; --(Odd/Even) domux setting
path_s.ea_output <= NB_DS_EA; -- dispmux & eamux & segop (unless Segment OP flag is set)
wrpath_s.wrip <= '1'; -- Update IP+nbreq register
next_state <= Swritemem; -- start write cycle
end if;
---------------------------------------------------------------------------------
-- Register or Memory to Segment Register
-- In case of memory, stalls until operand is read from memory
---------------------------------------------------------------------------------
when MOVRM2S =>
irq_blocked_s <= '1'; -- Block IRQ if asserted during next instr.
second_pass_s <= '0';
if instr.reg(1 downto 0)="01" then
proc_error_s<='1'; -- if segment register = CS report error
-- pragma synthesis_off
report "MOVRM2S : MOV CS,REG/Memory not valid" severity failure;
-- pragma synthesis_on
end if;
path_s.datareg_input<= DONTCARE(2 downto 0)& '1' & DONTCARE(2 downto 0); -- dimux & w=1 & seldreg
if instr.xmod="11" then -- Register to Segment Register , rm=reg field
path_s.alu_operation<= '0'&instr.rm & DONTCARE(3 downto 0) & ALU_PASSA; --selalua & selalub & aluopr
path_s.segreg_input <= SALUBUS_IN & instr.reg(1 downto 0); -- simux & selsreg
path_s.ea_output <= NB_CS_IP; -- IPREG+NB ADDR=CS:IP
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?