⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dp32_behaviour.vhd

📁 DLX CPU VHDL CODE UNIVERSITY
💻 VHD
字号:
---- $RCSfile: dp32_behaviour.vhd,v $-- $Revision: 1.7 $-- $Author: petera $-- $Date: 90/06/21 10:47:07 $--use work.dp32_types.all;architecture behaviour of dp32 is  subtype reg_addr is natural range 0 to 255;  type reg_array is array (reg_addr) of bit_32;begin -- behaviour of dp32  process    variable reg : reg_array;    variable PC : bit_32;    variable current_instr : bit_32;    variable op: bit_8;    variable r3, r1, r2 : reg_addr;    variable i8 : integer;    alias cm_i : bit is current_instr(19);    alias cm_V : bit is current_instr(18);    alias cm_N : bit is current_instr(17);    alias cm_Z : bit is current_instr(16);    variable cc_V, cc_N, cc_Z : bit;    variable temp_V, temp_N, temp_Z : bit;    variable displacement, effective_addr : bit_32;    procedure memory_read (addr : in bit_32;			 fetch_cycle : in boolean;			 result : out bit_32) is  begin    -- start bus cycle with address output    a_bus <= addr after Tpd;    fetch <= bool_to_bit(fetch_cycle) after Tpd;    wait until phi1 = '1';    if reset = '1' then      return;    end if;    --    -- T1 phase    --    read <= '1' after Tpd;    wait until phi1 = '1';    if reset = '1' then      return;    end if;    --    -- T2 phase    --    loop       wait until phi2 = '0';      if reset = '1' then      	return;       end if;      -- end of T2      if ready = '1' then      	result := d_bus;	exit;      end if;    end loop;    wait until phi1 = '1';    if reset = '1' then      return;    end if;    --    -- Ti phase at end of cycle    --    read <= '0' after Tpd;  end memory_read;  procedure memory_write (addr : in bit_32;			  data : in bit_32) is  begin    -- start bus cycle with address output    a_bus <= addr after Tpd;    fetch <= '0' after Tpd;    wait until phi1 = '1';    if reset = '1' then      return;    end if;    --    -- T1 phase    --    write <= '1' after Tpd;    wait until phi2 = '1';    d_bus <= data after Tpd;    wait until phi1 = '1';    if reset = '1' then      return;    end if;    --    -- T2 phase    --    loop       wait until phi2 = '0';      if reset = '1' then      	return;      end if;      -- end of T2      exit when ready = '1';    end loop;    wait until phi1 = '1';    if reset = '1' then      return;    end if;    --    -- Ti phase at end of cycle    --    write <= '0' after Tpd;    d_bus <= null after Tpd;  end memory_write;  procedure add (result : inout bit_32;		 op1, op2 : in integer;		 V, N, Z : out bit) is  begin    if op2 > 0 and op1 > integer'high-op2 then  -- positive overflow      int_to_bits(((integer'low+op1)+op2)-integer'high-1, result);      V := '1';    elsif op2 < 0 and op1 < integer'low-op2 then  -- negative overflow      int_to_bits(((integer'high+op1)+op2)-integer'low+1, result);      V := '1';    else      int_to_bits(op1 + op2, result);      V := '0';    end if;    N := result(31);    Z := bool_to_bit(result = X"0000_0000");  end add;  procedure subtract (result : inout bit_32;		      op1, op2 : in integer;		      V, N, Z : out bit) is  begin    if op2 < 0 and op1 > integer'high+op2 then  -- positive overflow      int_to_bits(((integer'low+op1)-op2)-integer'high-1, result);      V := '1';    elsif op2 > 0 and op1 < integer'low+op2 then  -- negative overflow      int_to_bits(((integer'high+op1)-op2)-integer'low+1, result);      V := '1';    else      int_to_bits(op1 - op2, result);      V := '0';    end if;    N := result(31);    Z := bool_to_bit(result = X"0000_0000");  end subtract;  procedure multiply (result : inout bit_32;		      op1, op2 : in integer;		      V, N, Z : out bit) is  begin    if ((op1>0 and op2>0) or (op1<0 and op2<0))  -- result positive	and (abs op1 > integer'high / abs op2) then  -- positive overflow      int_to_bits(integer'high, result);      V := '1';    elsif ((op1>0 and op2<0) or (op1<0 and op2>0))  -- result negative      	and ((- abs op1) < integer'low / abs op2) then  -- negative overflow      int_to_bits(integer'low, result);      V := '1';    else      int_to_bits(op1 * op2, result);      V := '0';    end if;    N := result(31);    Z := bool_to_bit(result = X"0000_0000");  end multiply;  procedure divide (result : inout bit_32;		    op1, op2 : in integer;		    V, N, Z : out bit) is  begin    if op2=0 then      if op1>=0 then 			  -- positive overflow	int_to_bits(integer'high, result);      else	int_to_bits(integer'low, result);      end if;      V := '1';    else      int_to_bits(op1 / op2, result);      V := '0';    end if;    N := result(31);    Z := bool_to_bit(result = X"0000_0000");  end divide;  begin    --    -- check for reset active    --    if reset = '1' then      read <= '0' after Tpd;      write <= '0' after Tpd;      fetch <= '0' after Tpd;      d_bus <= null after Tpd;      PC := X"0000_0000";      wait until reset = '0';    end if;    --    -- fetch next instruction    --    memory_read(PC, true, current_instr);    if reset /= '1' then      add(PC, bits_to_int(PC), 1, temp_V, temp_N, temp_Z);      --      -- decode & execute      --      op := current_instr(31 downto 24);      r3 := bits_to_natural(current_instr(23 downto 16));      r1 := bits_to_natural(current_instr(15 downto 8));      r2 := bits_to_natural(current_instr(7 downto 0));      i8 := bits_to_int(current_instr(7 downto 0));      case op is    	when op_add =>	  add(reg(r3), bits_to_int(reg(r1)), bits_to_int(reg(r2)), 	      cc_V, cc_N, cc_Z);      	when op_addq =>	  add(reg(r3), bits_to_int(reg(r1)), i8, 	      cc_V, cc_N, cc_Z);      	when op_sub =>	  subtract(reg(r3), bits_to_int(reg(r1)), bits_to_int(reg(r2)), 	      cc_V, cc_N, cc_Z);      	when op_subq =>	  subtract(reg(r3), bits_to_int(reg(r1)), i8, 	      cc_V, cc_N, cc_Z);      	when op_mul =>	  multiply(reg(r3), bits_to_int(reg(r1)), bits_to_int(reg(r2)), 	      cc_V, cc_N, cc_Z);      	when op_mulq =>	  multiply(reg(r3), bits_to_int(reg(r1)), i8, 	      cc_V, cc_N, cc_Z);      	when op_div =>	  divide(reg(r3), bits_to_int(reg(r1)), bits_to_int(reg(r2)), 	      cc_V, cc_N, cc_Z);      	when op_divq =>	  divide(reg(r3), bits_to_int(reg(r1)), i8, 	      cc_V, cc_N, cc_Z);      	when op_land =>	  reg(r3) := reg(r1) and reg(r2);	  cc_Z := bool_to_bit(reg(r3) = X"0000_0000");      	when op_lor =>	  reg(r3) := reg(r1) or reg(r2);	  cc_Z := bool_to_bit(reg(r3) = X"0000_0000");      	when op_lxor =>	  reg(r3) := reg(r1) xor reg(r2);	  cc_Z := bool_to_bit(reg(r3) = X"0000_0000");      	when op_lmask =>	  reg(r3) := reg(r1) and not reg(r2);	  cc_Z := bool_to_bit(reg(r3) = X"0000_0000");      	when op_ld =>      	  memory_read(PC, true, displacement);	  if reset /= '1' then	    add(PC, bits_to_int(PC), 1, temp_V, temp_N, temp_Z);	    add(effective_addr, 	      	bits_to_int(reg(r1)), bits_to_int(displacement),	      	temp_V, temp_N, temp_Z);	    memory_read(effective_addr, false, reg(r3));	  end if;      	when op_ldq =>      	  add(effective_addr,	      bits_to_int(reg(r1)), i8,	      temp_V, temp_N, temp_Z);	  memory_read(effective_addr, false, reg(r3));      	when op_st =>      	  memory_read(PC, true, displacement);	  if reset /= '1' then	    add(PC, bits_to_int(PC), 1, temp_V, temp_N, temp_Z);	    add(effective_addr, 	      	bits_to_int(reg(r1)), bits_to_int(displacement),	      	temp_V, temp_N, temp_Z);      	    memory_write(effective_addr, reg(r3));	  end if;      	when op_stq =>      	  add(effective_addr,	      bits_to_int(reg(r1)), i8,	      temp_V, temp_N, temp_Z);	  memory_write(effective_addr, reg(r3));      	when op_br =>      	  memory_read(PC, true, displacement);	  if reset /= '1' then	    add(PC, bits_to_int(PC), 1, temp_V, temp_N, temp_Z);	    add(effective_addr, 	      	bits_to_int(PC), bits_to_int(displacement),	      	temp_V, temp_N, temp_Z);	    if ((cm_V and cc_V) or (cm_N and cc_N) or (cm_Z and cc_Z)) 	      	= cm_i then	      PC := effective_addr;	    end if;	  end if;      	when op_bi =>      	  memory_read(PC, true, displacement);	  if reset /= '1' then	    add(PC, bits_to_int(PC), 1, temp_V, temp_N, temp_Z);	    add(effective_addr, 	      	bits_to_int(reg(r1)), bits_to_int(displacement),	      	temp_V, temp_N, temp_Z);	    if ((cm_V and cc_V) or (cm_N and cc_N) or (cm_Z and cc_Z)) 	      	= cm_i then	      PC := effective_addr;	    end if;	  end if;      	when op_brq =>	  add(effective_addr,	      bits_to_int(PC), i8,	      temp_V, temp_N, temp_Z);	  if ((cm_V and cc_V) or (cm_N and cc_N) or (cm_Z and cc_Z)) 	      = cm_i then	    PC := effective_addr;	  end if;      	when op_biq =>	  add(effective_addr,	      bits_to_int(reg(r1)), i8,	      temp_V, temp_N, temp_Z);	  if ((cm_V and cc_V) or (cm_N and cc_N) or (cm_Z and cc_Z)) 	      = cm_i then	    PC := effective_addr;	  end if;      	when others =>      	  assert false report "illegal instruction" severity warning;      end case;    end if;  -- reset /= '1'  end process;end behaviour;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -