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

📄 m68k.vhd

📁 motorola m68k VHDL描述
💻 VHD
📖 第 1 页 / 共 3 页
字号:
--------------------------------------------------------------------------
--------------------------------------------------------------------------
--	File Name 	: 68000.v
--	Author(s)	: Ric Heishman, Dave Hollinden, John Krautheim,
--			  Tim McBrayer and Praveen Sinha.
--	Affiliation	: Laboratory for Digital Design Environments
--			  Department of Electrical & Computer Engineering
--			  University of Cincinnati
--	Date Created	: June, 1991.
--	Introduction	: A behavioral description of Motorola's 68000,
--			  written in a synthesizable subset of VHDL.
--	Source		: The source is an ISPS description written by
--                        Mich Norton at the Carnegie-Mellon University. 
--                        Obtained in ISPS from the High-Level Synthesis
--                        Workshop Repository.
--
--	Modified For Synthesis by Jay(anta) Roy, University of Cincinnati.
--	Date Modified	: Sept, 91.
--
--	Disclaimer	: This comes with absolutely no guarantees of any 
--			  kind (just stating the obvious ...)
--
--	Acknowledgement : The Distributed Synthesis Systems research at 
--			  the Laboratory for Digital Design Environments,
--			  University of Cincinnati, is sponsored in part 
--			  by the Defense Advanced Research Projects Agency 
--			  under order number 7056 monitored by the Federal 
--			  Bureau of Investigation under contract number 
--			  J-FBI-89-094.
--
--------------------------------------------------------------------------
--------------------------------------------------------------------------

--|  Types package.
--|  This package defined the types and structures used in the simulation
--|  The record is used to pass "global" data to procedures.

package types is
   type regarray is array(0 to 7) of BIT_VECTOR(31 downto 0);
   type memarray is array(0 to 255) of BIT_VECTOR(7 downto 0);
   type var_record is record
       dummy: integer;
       dreg: regarray;
       areg: regarray;
       pc: BIT_VECTOR(31 downto 0);
       sr: BIT_VECTOR(15 downto 0);
       prefetch: BIT;
       illegal_instruction: BIT;
       privilege_violation: BIT;
       temp64: BIT_VECTOR(63 downto 0);
       temp32: BIT_VECTOR(31 downto 0);  
       temp16: BIT_VECTOR(15 downto 0);  
       temp8: BIT_VECTOR(7 downto 0);
       nzvc: BIT_VECTOR(3 downto 0);
       indirbuf: BIT_VECTOR(15 downto 0);
       nir: BIT_VECTOR(15 downto 0);
       ir: BIT_VECTOR(15 downto 0);
       m: memarray;
   end record;
end types;

use Work.types.all;
use Work.functions.all;
use Std.textio.all;


entity MC68000 is
end MC68000;


architecture MC68000 of MC68000 is
begin

main: process

   variable var: var_record;
         alias sysbyte: BIT_VECTOR(7 downto 0) is var.sr(15 downto 8);
         alias tmode: BIT is sysbyte(7);
         alias smode: BIT is sysbyte(5);
         alias imask: BIT_VECTOR(2 downto 0) is sysbyte(2 downto 0);
         alias userbyte: BIT_VECTOR(7 downto 0) is sysbyte(7 downto 0);
         alias x: BIT is userbyte(4);
         alias n: BIT is userbyte(3);
         alias z: BIT is userbyte(2);
         alias v: BIT is userbyte(1);
         alias c: BIT is userbyte(0);
         alias ntemp: BIT is var.nzvc(3);
         alias ztemp: BIT is var.nzvc(2);
         alias vtemp: BIT is var.nzvc(1);
         alias ctemp: BIT is var.nzvc(0);
         alias d_a: BIT is var.indirbuf(15);
         alias r: BIT_VECTOR(2 downto 0) is var.indirbuf(14 downto 12);
         alias w_l: BIT is var.indirbuf(11);
         alias di: BIT_VECTOR(7 downto 0) is var.indirbuf(7 downto 0);
         alias op_set: BIT_VECTOR(3 downto 0) is var.ir(15 downto 12);
         alias op_field_1: BIT_VECTOR(2 downto 0) is var.ir(11 downto 9);
         alias data: BIT_VECTOR(2 downto 0) is var.ir(11 downto 9);
         alias c_r: BIT_VECTOR(2 downto 0) is var.ir(11 downto 9);
         alias cond: BIT_VECTOR(3 downto 0) is var.ir(11 downto 8);
         alias eadd_b: BIT_VECTOR(5 downto 0) is var.ir(11 downto 6);
         alias reg_b: BIT_VECTOR(2 downto 0) is eadd_b(5 downto 3);
         alias mode_b: BIT_VECTOR(2 downto 0) is eadd_b(2 downto 0);
         alias op_field_2a: BIT is var.ir(8);
         alias dir: BIT is var.ir(8);
         alias op_field_2ab: BIT_VECTOR(1 downto 0) is var.ir(8 downto 7);
         alias op_field_2: BIT_VECTOR(2 downto 0) is var.ir(8 downto 6);
         alias op_mode: BIT_VECTOR(2 downto 0) is var.ir(8 downto 6);
         alias op_field_2bc: BIT_VECTOR(1 downto 0) is var.ir(7 downto 6);
         alias mode: BIT_VECTOR(1 downto 0) is var.ir(7 downto 6);
         alias size: BIT_VECTOR(1 downto 0) is var.ir(7 downto 6);
         alias value: BIT_VECTOR(7 downto 0) is var.ir(7 downto 0);
         alias sz: BIT is var.ir(6);
         alias i_r: BIT is var.ir(5);
         alias op_field_3ab: BIT_VECTOR(1 downto 0) is var.ir(5 downto 4);
         alias op_field_3: BIT_VECTOR(2 downto 0) is var.ir(5 downto 3);
         alias eadd_a: BIT_VECTOR(5 downto 0) is var.ir(5 downto 0);
         alias mode_a: BIT_VECTOR(2 downto 0) is eadd_a(5 downto 3);
         alias reg_a: BIT_VECTOR(2 downto 0) is eadd_a(2 downto 0);
         alias op_field_3bc: BIT_VECTOR(1 downto 0) is var.ir(4 downto 3);
         alias r_m: BIT is var.ir(3);
         alias vector: BIT_VECTOR(3 downto 0) is var.ir(3 downto 0);
         alias op_field_4: BIT_VECTOR(2 downto 0) is var.ir(2 downto 0);

   file outfile: text is out "outfile";
   variable L: line;
   variable S: string(1 to 25);

 procedure plus (Left, Right, return_vector: inout Bit_Vector(31 downto 0)) is
  variable carry : Bit := '0';
  variable dummy : Bit_Vector(0 to 2);
  begin
     for i in 0 to 31 loop
        dummy(0) := Left(i);
        dummy(1) := Right(i);
        dummy(2) := carry;
        case dummy is
          when "000" =>
            return_vector(i) := '0';
            carry := '0';
          when "001" =>
            return_vector(i) := '1';
            carry := '0';
          when "010" =>
            return_vector(i) := '1';
            carry := '0';
          when "011" =>
            return_vector(i) := '0';
            carry := '1';
          when "100" =>
            return_vector(i) := '1';
            carry := '0';
          when "101" =>
            return_vector(i) := '0';
            carry := '1';
          when "110" =>
            return_vector(i) := '0';
            carry := '1';
          when "111" =>
            return_vector(i) := '1';
            carry := '1';
        end case;
     end loop;
  end;


function ret_string (instring: in string) return string is
begin
   return instring;
end ret_string;


procedure instr_stream_fetch(isf_nir: inout bit_vector(15 downto 0); 
                             isf_pc: inout bit_vector(31 downto 0);
                             isf_prefetch: in bit;
                             isf_m: in memarray;
                             isf_output: out bit_vector(15 downto 0)) is
   variable isf_int: integer;
   variable fixit: bit_vector(31 downto 0);
   variable two: bit_vector(31 downto 0);
begin
   write(L,ret_string("PC: "));
   write(L,isf_pc);
   writeline(outfile,L);
   isf_output := isf_nir;
   isf_int := bits_to_int(isf_pc);
   two := x"00000002";
   fixit := isf_pc;
   plus(fixit,two,isf_pc);
   if (isf_prefetch = '1') then
	  isf_int := bits_to_int(isf_pc);
          isf_nir(15 downto 8) := isf_m(isf_int);
	  isf_int := isf_int + 1;
	  isf_nir(7 downto 0) := isf_m(isf_int);
   end if;
end instr_stream_fetch;

procedure immediate(imm_size: inout bit_vector(1 downto 0);
		    imm_nir: inout BIT_VECTOR(15 downto 0);
		    imm_pc: inout BIT_VECTOR(31 downto 0);
		    imm_prefetch: inout bit;
		    imm_m: inout memarray;
		    imm_output: out BIT_VECTOR(31 downto 0)) is
begin
   case imm_size is
      when "00" => instr_stream_fetch(imm_nir,imm_pc,imm_prefetch,
				 imm_m,imm_output(15 downto 0));
      when "01" => instr_stream_fetch(imm_nir,imm_pc,imm_prefetch,
				 imm_m,imm_output(15 downto 0));
      when "10" => instr_stream_fetch(imm_nir,imm_pc,imm_prefetch,
				 imm_m,imm_output(31 downto 16));
	           instr_stream_fetch(imm_nir,imm_pc,imm_prefetch,
				 imm_m,imm_output(15 downto 0));
      when "11" => null;
   end case;
end immediate;

procedure addr_calc(acvar: inout var_record;
                    acmode: in bit_vector(2 downto 0);
                    acreg: in bit_vector(2 downto 0);
                    ac_result: inout bit_vector(31 downto 0)) is

   variable ac_int: integer;
   variable ac_dummy: bit_vector(15 downto 0);

begin
   case acmode is
      when "000"|"001" => 
		 null;
      when "010" =>
		 ac_int := bits_to_int(acreg);
		 ac_result := acvar.areg(ac_int);
      when "011" => 
		 case acvar.ir(7 downto 6) is
		    when "00" => 
                       ac_int := bits_to_int(acreg);
                       ac_result := acvar.areg(ac_int);
                       if (acreg = "111") then 
                          acvar.areg(ac_int) := acvar.areg(ac_int) + x"00000002";
                       else
                          acvar.areg(ac_int) := acvar.areg(ac_int) + x"00000001";
                       end if;
		    when "01" => 
			   ac_int := bits_to_int(acreg);
			   ac_result := acvar.areg(ac_int);
			   acvar.areg(ac_int) := acvar.areg(ac_int) + x"00000002";
		    when "10" => 
			   ac_int := bits_to_int(acreg);
			   ac_result := acvar.areg(ac_int);
			   acvar.areg(ac_int) := acvar.areg(ac_int) + x"00000004";
		    when others => null;
		 end case;
      when "100" => 
		 case acvar.ir(7 downto 6) is
		    when "00" => 
			   if (acreg = "111") then 
                  acvar.areg(7) := acvar.areg(7) - "10";
			   else 
                              ac_int := bits_to_int(acreg);
                              acvar.areg(ac_int) := acvar.areg(ac_int) - x"00000001";
			      ac_result := acvar.areg(ac_int);
			   end if;
		    when "01" => 
			   ac_int := bits_to_int(acreg);
			   acvar.areg(ac_int) := acvar.areg(ac_int) - x"00000002";
			   ac_result := acvar.areg(ac_int);
		    when "10" => 
			   ac_int := bits_to_int(acreg);
			   acvar.areg(ac_int) := acvar.areg(ac_int) - x"00000004";
			   ac_result := acvar.areg(ac_int);
		    when others => null;
		 end case;
      when "101" => 
               ac_int := bits_to_int(acreg);
               instr_stream_fetch(acvar.nir, acvar.pc, acvar.prefetch, acvar.m,
                                  ac_dummy);
               ac_result := acvar.areg(ac_int) + ac_dummy;
      when "110" => 
         ac_int := bits_to_int(acreg);
         instr_stream_fetch(acvar.nir, acvar.pc, acvar.prefetch, acvar.m,
                            acvar.indirbuf);
         if acvar.indirbuf(15) = '0' then
            if acvar.indirbuf(11) = '0' then
               ac_int := bits_to_int(acvar.indirbuf(14 downto 12));
               acvar.temp32 := acvar.dreg(ac_int);
               ac_result := acvar.areg(ac_int) + 
                            acvar.temp32(15 downto 0) +
                            acvar.indirbuf(7 downto 0);
            else
               ac_int := bits_to_int(acvar.indirbuf(14 downto 12));
               ac_result := acvar.areg(ac_int) + acvar.dreg(ac_int) +
                            acvar.indirbuf(7 downto 0);
            end if;
         else
            if acvar.indirbuf(11) = '0' then
               ac_int := bits_to_int(acvar.indirbuf(14 downto 12));
               acvar.temp32 := acvar.dreg(ac_int);
               ac_result := acvar.areg(ac_int) + 
                            acvar.temp32(15 downto 0) +
                            acvar.indirbuf(7 downto 0);
            else
               ac_int := bits_to_int(acvar.indirbuf(14 downto 12));
               ac_result := acvar.areg(ac_int) + acvar.areg(ac_int) +
                            acvar.indirbuf(7 downto 0);
            end if;
         end if;
      when "111" =>
         case acreg is
            when "000" =>
               instr_stream_fetch(acvar.nir, acvar.pc, acvar.prefetch, acvar.m,
                                  ac_result);
            when "001" =>
               instr_stream_fetch(acvar.nir, acvar.pc, acvar.prefetch, acvar.m,
                                  ac_result(31 downto 16));
               if acvar.prefetch = '0' then
                  ac_int := bits_to_int(acvar.pc);
                  ac_result(15 downto 8) := acvar.m(ac_int);
                  ac_int := ac_int + 1;
                  ac_result(7 downto 0) := acvar.m(ac_int);
                  acvar.pc := acvar.pc + x"02";
               else
                  instr_stream_fetch(acvar.nir, acvar.pc, acvar.prefetch,
                                     acvar.m, ac_result(15 downto 0));
               end if;
            when "010" =>
               acvar.temp32 := acvar.pc;
               instr_stream_fetch(acvar.nir, acvar.pc, acvar.prefetch, acvar.m,
                                  ac_result(15 downto 0));
               ac_result := ac_result + acvar.temp32;
            when "011" =>
               ac_result := acvar.pc;
               instr_stream_fetch(acvar.nir, acvar.pc, acvar.prefetch, acvar.m,
                                  acvar.indirbuf);
               if acvar.indirbuf(15) = '0' then
                  if acvar.indirbuf(11) = '0' then
                     ac_int := bits_to_int(acvar.indirbuf(14 downto 12));
                     ac_dummy := acvar.dreg(ac_int);
                     ac_result := ac_result + ac_dummy(15 downto 0) + 
                                  acvar.indirbuf(7 downto 0);
                  else
                     ac_result := ac_result + ac_dummy +
                                  acvar.indirbuf(7 downto 0);
                  end if;
               else
                  if acvar.indirbuf(11) = '0' then
                     ac_int := bits_to_int(acvar.indirbuf(14 downto 12));
                     ac_dummy := acvar.areg(ac_int);
                     ac_result := ac_result + ac_dummy(15 downto 0) + 
                                  acvar.indirbuf(7 downto 0);
                  else
                     ac_result := ac_result + ac_dummy +
                                  acvar.indirbuf(7 downto 0);
                  end if;
               end if;
            when others => null;
         end case;
   end case;
end addr_calc;

procedure opr_fetch(    opvar: inout var_record;
                        op_size: inout bit_vector(1 downto 0);
			op_mode: in bit_vector(2 downto 0);
			op_reg: in bit_vector(2 downto 0);
                        op_result: out bit_vector(31 downto 0)) is
   variable op_int, op_int1 : integer;
   variable op_dummy : bit_vector(31 downto 0);
   variable op_dummy2: bit_vector(5 downto 0);
begin
   op_dummy2(5 downto 3) := op_mode;
   op_dummy2(2 downto 0) := op_reg;
   op_int := bits_to_int(op_dummy2);
   case op_int is
      when 0 to 7  => op_result := opvar.dreg(bits_to_int(op_reg));
      when 8 to 15 => op_result := opvar.areg(bits_to_int(op_reg));
      when 60 => immediate(op_size,opvar.nir,opvar.pc,opvar.prefetch,
                           opvar.m,op_result);
      when others =>
         case op_size is
            when "00" =>
               addr_calc(opvar, op_mode, op_reg, op_dummy);
               op_int1 := bits_to_int(op_dummy(7 downto 0));
               op_result(7 downto 0) := opvar.m(op_int1);
            when "01" =>
               addr_calc(opvar, op_mode, op_reg, op_dummy);
               op_int1 := bits_to_int(op_dummy(7 downto 0));
               op_result(15 downto 8) := opvar.m(op_int1);
               op_int1 := op_int1 + 1;
               op_result(7 downto 0) := opvar.m(op_int1);
            when "10" =>
               addr_calc(opvar, op_mode, op_reg, op_dummy);
               op_int1 := bits_to_int(op_dummy(7 downto 0));
               op_result(31 downto 24) := opvar.m(op_int1);
               op_int1 := op_int1 + 1;
               op_result(23 downto 16) := opvar.m(op_int1);
               op_int1 := op_int1 + 1;
               op_result(15 downto 8) := opvar.m(op_int1);
               op_int1 := op_int1 + 1;
               op_result(7 downto 0) := opvar.m(op_int1);
            when others => null;
         end case;
   end case;
end opr_fetch;

procedure opr_write(owvar: inout var_record;
                    ow_size: inout bit_vector(1 downto 0);
                    ow_mode: inout bit_vector(2 downto 0);
                    ow_reg: inout bit_vector(2 downto 0);
                    ow_value: inout bit_vector(31 downto 0)) is
variable ow_int, ow_int1: integer;
variable ow_dummy: bit_vector(31 downto 0);

begin
   ow_int := bits_to_int(ow_reg);
   case ow_mode is
      when "000" =>
         case ow_size is
            when "00" =>
               ow_dummy := owvar.dreg(ow_int);
               ow_dummy(7 downto 0) := ow_value(7 downto 0);
               owvar.dreg(ow_int) := ow_dummy;
            when "01" =>
               ow_dummy := owvar.dreg(ow_int);
               ow_dummy(15 downto 0) := ow_value(15 downto 0);
               owvar.dreg(ow_int) := ow_dummy;
            when "10" =>
               owvar.dreg(ow_int) := ow_value;
            when "11" => null;
         end case;
      when "001" =>
         owvar.areg(ow_int) := ow_value;
      when others =>
         case ow_size is
            when "00" =>
               addr_calc(owvar, ow_mode, ow_reg, ow_dummy);
               ow_int1 := bits_to_int(ow_dummy(7 downto 0));
               owvar.m(ow_int1) := ow_value(7 downto 0);
            when "01" =>
               addr_calc(owvar, ow_mode, ow_reg, ow_dummy);
               ow_int1 := bits_to_int(ow_dummy(7 downto 0));

⌨️ 快捷键说明

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