-------------------------------------------------------------------------- -------------------------------------------------------------------------- -- 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)); owvar.m(ow_int1) := ow_value(15 downto 8); ow_int1 := ow_int1 + 1; owvar.m(ow_int1) := ow_value(7 downto 0); when "10" => 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(31 downto 24); ow_int1 := ow_int1 + 1; owvar.m(ow_int1) := ow_value(23 downto 16); ow_int1 := ow_int1 + 1; owvar.m(ow_int1) := ow_value(15 downto 8); ow_int1 := ow_int1 + 1; owvar.m(ow_int1) := ow_value(7 downto 0); when "11" => null; end case; end case; end opr_write; procedure movep is begin null; end movep; procedure btst_d is begin null; end btst_d; procedure bchg_d is begin null; end bchg_d; procedure bclr_d is begin null; end bclr_d; procedure bset_d is begin null; end bset_d; procedure btst_s is begin null; end btst_s; procedure bchg_s is begin null; end bchg_s; procedure bclr_s is begin null; end bclr_s; procedure bset_s is begin null; end bset_s; procedure ori_to_ccr is begin null; end ori_to_ccr; procedure ori_to_sr is begin null; end ori_to_sr; function bitor(left, right: in bit_vector(31 downto 0)) return bit_vector is variable bittemp: bit_vector(31 downto 0); begin for i in 0 to 31 loop bittemp(i) := left(i) or right(i); end loop; return bittemp; end bitor; procedure test(testvar: inout var_record; testsize: in bit_vector(1 downto 0); testval: in bit_vector(31 downto 0)) is begin case testsize is when "00" => testvar.nzvc(3) := testval(7); if (testval(7 downto 0) = x"00") then testvar.nzvc(2) := '1'; else testvar.nzvc(2) := '0'; end if; when "01" => testvar.nzvc(3) := testval(15); if (testval(15 downto 0) = x"0000") then testvar.nzvc(2) := '1'; else testvar.nzvc(2) := '0'; end if; when "10" => testvar.nzvc(3) := testval(31); if (testval(31 downto 0) = x"00000000") then testvar.nzvc(2) := '1'; else testvar.nzvc(2) := '0'; end if; when others => null; end case; end test; procedure ori(orvar: inout var_record) is variable ortemp1: bit_vector(31 downto 0); variable ortemp2: bit_vector(31 downto 0); variable ortemp3: bit_vector(31 downto 0); begin write(L,ret_string("Entered ORI")); writeline(outfile,L); immediate(orvar.ir(7 downto 6), orvar.nir, orvar.pc, orvar.prefetch, orvar.m, ortemp2); opr_fetch(orvar,orvar.ir(7 downto 6),orvar.ir(5 downto 3),orvar.ir(2 downto 0),ortemp1); ortemp3 := bitor(ortemp1,ortemp2); opr_write(orvar,orvar.ir(7 downto 6),orvar.ir(5 downto 3),orvar.ir(2 downto 0),ortemp3); test(orvar, orvar.ir(7 downto 6), ortemp3); orvar.sr(11) := orvar.nzvc(3); orvar.sr(10) := orvar.nzvc(2); orvar.sr(9 downto 8) := "00"; write(L,ret_string("Memory location 0020 (hex) contains the following: ")); writeline(outfile,L); write(L,ret_string(" ")); write(L,orvar.m(32)); write(L,orvar.m(33)); write(L,orvar.m(34)); write(L,orvar.m(35)); writeline(outfile,L); end ori; procedure andi_to_ccr is begin null; end andi_to_ccr; procedure andi_to_sr is begin null; end andi_to_sr; procedure andi is begin null; end andi; procedure subi is begin null; end subi; procedure addi is begin null; end addi; procedure eori_to_ccr is begin null; end eori_to_ccr; procedure eori_to_sr is begin null; end eori_to_sr; procedure eori is begin null; end eori; procedure cmpi is begin null; end cmpi; procedure move is begin null; end move; procedure movea is begin null; end movea; procedure move_from_sr is begin null; end move_from_sr; procedure negx is begin null; end negx; procedure clr is begin null; end clr; procedure move_to_ccr(mov_var: inout var_record) is variable of_result :bit_vector(31 downto 0); variable movesize :bit_vector(1 downto 0) := "01"; begin write(L,ret_string("Entering Move to CCR")); writeline(outfile,L); opr_fetch(mov_var,movesize,mov_var.ir(5 downto 3),mov_var.ir(2 downto 0),of_result); mov_var.sr(15 downto 8) := of_result(7 downto 0); write(L,ret_string("SR: ")); write(L,mov_var.sr); writeline(outfile,L); end move_to_ccr; procedure neg is begin null; end neg; procedure move_to_sr is begin null; end move_to_sr; procedure nott is begin null; end nott; procedure nbcd is begin null; end nbcd; procedure swap(swvar: inout var_record) is variable regno:integer; begin write(L,ret_string("Entering Swap")); writeline(outfile,L); write(L,ret_string("Original register: ")); write(L,swvar.dreg(2)); writeline(outfile,L); regno := bits_to_int(swvar.ir(2 downto 0)); write(L,regno); writeline(outfile,L); swvar.temp16 := swvar.dreg(regno)(15 downto 0); swvar.dreg(regno)(15 downto 0):= swvar.dreg(regno)(31 downto 16); swvar.dreg(regno)(31 downto 16):= swvar.temp16; write(L,ret_string("Swapped register: ")); write(L,swvar.dreg(2)); writeline(outfile,L); end swap; procedure pea is begin null; end pea; procedure ext_w is begin null; end ext_w; procedure ext_l is begin null; end ext_l; procedure movem_rtoea is begin null; end movem_rtoea; procedure illegal is begin null; end illegal; procedure tas is begin null; end tas; procedure tst is begin null; end tst; procedure movem_eator is begin null; end movem_eator; procedure trap is begin null; end trap; procedure link is begin null; end link; procedure unlk is begin null; end unlk; procedure move_to_usp is begin null; end move_to_usp; procedure move_from_usp is begin null; end move_from_usp; procedure reset is begin null; end reset; procedure nop is begin write(L,ret_string("Arrived at Nop instruction")); writeline(outfile,L); null; end nop; procedure stop is begin write(L,ret_string("Arrived at Stop instruction")); writeline(outfile,L); wait; end stop; procedure rte is begin null; end rte; procedure rts is begin null; end rts; procedure trapv is begin null; end trapv; procedure rtr is begin null; end rtr; procedure jsr is begin null; end jsr; procedure jmp(jmpvar: inout var_record) is variable addr :integer; variable acc_result :bit_vector(31 downto 0); begin write(L,ret_string("Arrived at Jmp instruction")); writeline(outfile,L); jmpvar.prefetch := '0'; addr_calc(jmpvar,jmpvar.ir(5 downto 3),jmpvar.ir(2 downto 0),acc_result); jmpvar.pc := acc_result; addr := bits_to_int(jmpvar.pc); jmpvar.nir(15 downto 8) := jmpvar.m(addr); jmpvar.nir(7 downto 0) := jmpvar.m(addr + 1); jmpvar.prefetch := '1'; end jmp; procedure chk is begin null; end chk; procedure lea(leavar:inout var_record) is variable acc_result: bit_vector(31 downto 0); variable regno: integer; variable temp: bit_vector(2 downto 0); begin write(L,ret_string("Arrived at Lea instruction")); writeline(outfile,L); addr_calc(leavar,leavar.ir(5 downto 3),leavar.ir(2 downto 0),acc_result); temp := leavar.ir(11 downto 9); regno := bits_to_int(temp); leavar.areg(regno) := acc_result; write(L,ret_string("Areg(3): ")); write(L,leavar.areg(3)); writeline(outfile,L); end lea; procedure exception_check is begin null; end; procedure addq is begin null; end; procedure subq is begin null; end; procedure dbcc is begin null; end; procedure cc(ccvar :inout var_record; cond:in bit_vector(3 downto 0); res :out bit) is variable condn :integer; begin condn := bits_to_int(cond); case condn is when 0 => res := '1'; when 1 => res := '0'; when 2 => res := (not(ccvar.sr(8))) and (not(ccvar.sr(10))); when 3 => res := ccvar.sr(8) or ccvar.sr(10); when 4 => res := not(ccvar.sr(8)); when 5 => res := ccvar.sr(8); when 6 => res := not(ccvar.sr(10)); when 7 => res := ccvar.sr(10); when 8 => res := not(ccvar.sr(9)); when 9 => res := ccvar.sr(9); when 10 => res := not(ccvar.sr(11)); when 11 => res := ccvar.sr(11); when 12 => res := ((ccvar.sr(11) and ccvar.sr(9)) or (not(ccvar.sr(11)) and not(ccvar.sr(9)))); when 13 => res := ((ccvar.sr(11) and not(ccvar.sr(9))) or (not(ccvar.sr(11)) and ccvar.sr(9))); when 14 => res := (((ccvar.sr(11) and ccvar.sr(9)) or (not(ccvar.sr(11)) and not(ccvar.sr(9)))) and (not(ccvar.sr(10)))); when 15 => res := ((ccvar.sr(10) or (ccvar.sr(11) and not(ccvar.sr(9)))) or (not(ccvar.sr(11)) and ccvar.sr(9))); when others => null; end case; end cc; procedure scc(sccvar :inout var_record) is variable result : bit_vector(31 downto 0); variable res : bit; variable sccdummy: bit_vector(1 downto 0) := "00"; variable sccdummy2: bit_vector(31 downto 0); begin write(L,ret_string("Arrived at Scc instruction")); writeline(outfile,L); opr_fetch(sccvar,sccdummy,sccvar.ir(5 downto 3),sccvar.ir(2 downto 0),result); cc(sccvar,sccvar.ir(11 downto 8),res); case res is when '0' => sccdummy2 := x"00000000"; opr_write(sccvar,sccdummy,sccvar.ir(5 downto 3),sccvar.ir(2 downto 0),sccdummy2); when '1' => sccdummy2 := x"000000ff"; opr_write(sccvar,sccdummy,sccvar.ir(5 downto 3),sccvar.ir(2 downto 0),sccdummy2); end case; write(L,ret_string("Memory location 0020 (hex) contains the following: ")); writeline(outfile,L); write(L,sccvar.m(32)); writeline(outfile,L); end scc; procedure bsr is begin null; end; procedure bcc is begin null; end; procedure moveq is begin null; end; procedure divu is begin null; end; procedure divs is begin null; end; procedure sbcd is begin null; end; procedure orr is begin null; end; procedure suba is begin null; end; procedure subx is begin null; end; procedure subb is begin null; end; procedure cmp is begin null; end; procedure cmpa is begin null; end; procedure cmpm is begin null; end; procedure eor is begin null; end; procedure mulu is begin null; end; procedure muls is begin null; end; procedure abcd is begin null; end; procedure exgd is begin null; end; procedure exga is begin null; end; procedure exgm is begin null; end; procedure andd is begin null; end; procedure adda is begin null; end; procedure addx is begin null; end; procedure add is begin null; end; procedure asm is begin null; end; procedure lsm is begin null; end; procedure roxm is begin null; end; procedure rom is begin null; end; procedure asr is begin null; end; procedure lsr is begin null; end; procedure roxr is begin null; end; procedure ror is begin null; end; begin --main loop var.m(0) := x"00"; var.m(1) := x"00"; var.m(2) := x"00"; var.m(3) := x"FF"; -- set stack pointer to the top of memory var.m(4) := x"00"; var.m(5) := x"00"; var.m(6) := x"00"; var.m(7) := x"08"; -- set initial PC = 8 var.m(8) := x"4e"; -- jump var.m(9) := x"d1"; var.m(10) := x"4e"; -- stop var.m(11) := x"72"; var.m(12) := x"48"; -- swap var.m(13) := x"42"; var.m(14) := x"47"; -- lea var.m(15) := x"d1"; var.m(16) := x"44"; -- move_to_ccr var.m(17) := x"d4"; var.m(18) := x"54"; -- Scc var.m(19) := x"d5"; var.m(20) := x"00"; -- ORI var.m(21) := x"95"; var.m(22) := x"0f"; var.m(23) := x"0f"; var.m(24) := x"0f"; var.m(25) := x"0f"; var.m(26) := x"4e"; -- stop var.m(27) := x"72"; var.areg(1) := x"0000000c"; var.dreg(2) := x"12345678"; var.areg(4) := x"00000009"; var.areg(5) := x"00000020"; var.prefetch := '1'; var.sr := x"05c0"; var.temp32(31 downto 24) := var.m(0); var.temp32(23 downto 16) := var.m(1); var.temp32(15 downto 8) := var.m(2); var.temp32(7 downto 0) := var.m(3); var.areg(7) := var.temp32; var.temp32(31 downto 24) := var.m(4); var.temp32(23 downto 16) := var.m(5); var.temp32(15 downto 8) := var.m(6); var.temp32(7 downto 0) := var.m(7); var.pc := var.temp32; var.dummy := bits_to_int(var.pc); var.temp16(15 downto 8) := var.m(var.dummy); var.dummy := var.dummy + 1; var.temp16(7 downto 0) := var.m(var.dummy); var.nir := var.temp16; loop instr_stream_fetch(var.nir, var.pc, var.prefetch, var.m, var.ir); case op_set is --choose the proper type of execution when "0000" => if (op_field_2a = '1') then if (op_field_3 = "001") then movep; else case op_field_2bc is when "00" => btst_d; when "01" => bchg_d; when "10" => bclr_d; when "11" => bset_d; end case; end if; else case op_field_1 is when "100" => case op_field_2bc is when "00" => btst_s; when "01" => bchg_s; when "10" => bclr_s; when "11" => bset_s; end case; when "000" => if (var.ir(5 downto 0) = x"111100") then case size is when "00" => ori_to_ccr; when "01" => ori_to_sr; when others =>n := '1'; end case; else ori(var); end if; when "001" => if (var.ir(5 downto 0) = x"111100") then case size is when "00" => andi_to_ccr; when "01" => andi_to_sr; when others =>n := '1'; end case; else andi; end if; when "010" => subi; when "011" => addi; when "101" => if (var.ir(5 downto 0) = x"111100") then case size is when "00" => eori_to_ccr; when "01" => eori_to_sr; when others =>n := '1'; end case; else eori; end if; when "110" => cmpi; when others =>n := '1'; end case; end if; when "0001"|"0010"|"0011" => case op_set is when "0010"|"0011" => if (op_field_2 = "001") then movea; else move; end if; when others => move; end case; when "0100" => var.dummy := bits_to_int(var.ir(11 downto 0)); case var.dummy is when 192 to 255 => move_from_sr; when 0 to 191 => negx; when 512 to 703 => clr; when 1216 to 1279 => move_to_ccr(var); when 1024 to 1215 => neg; when 1728 to 1792 => move_to_sr; when 1536 to 1727 => nott; when 2048 to 2111 => nbcd; when 2112 to 2119 => swap(var); when 2120 to 2175 => pea; when 2176 to 2183 => ext_w; when 2240 to 2247 => ext_l; when 2184 to 2239|2248 to 2303 => movem_rtoea; when 2812 => illegal; when 2752 to 2811 => tas; when 2560 to 2751 => tst; when 3200 to 3327 => movem_eator; when 3655 to 3663 => trap; when 3664 to 3671 => link; when 3672 to 3679 => unlk; when 3680 to 3687 => move_to_usp; when 3688 to 3695 => move_from_usp; when 3696 => reset; when 3697 => nop; when 3698 => stop; when 3699 => rte; when 3701 => rts; when 3702 => trapv; when 3703 => rtr; when 3712 to 3775 => jsr; when 3776 to 3839 => jmp(var); when 384 to 447|896 to 959|1408 to 1471| 1920 to 1983|2432 to 2495|2944 to 3007| 3456 to 3519|3968 to 4031 => chk; when 448 to 511|960 to 1023|1472 to 1535| 1984 to 2047|2496 to 2559|3008 to 3071| 3520 to 3583|4032 to 4095 => lea(var); when others =>n := '1'; end case; when "0101" => case op_field_2 is when "000" | "001" | "010" => addq; when "100" | "101" | "110" => subq; when "011" | "111" => if op_field_3 = "001" then dbcc; else scc(var); end if; end case; when "0110" => if op_field_1 & op_field_2a = "0001" then bsr; else bcc; end if; when "0111" => moveq; when "1000" => var.dummy := bits_to_int(op_field_2 & op_field_3ab); case var.dummy is when 12 to 15 => divu; when 28 to 31 => divs; when 16 => sbcd; when others => orr; end case; when "1001" => if op_field_2bc = "11" then suba; else if op_field_2a & op_field_3ab = "100" then subx; else subb; end if; end if; when "1011" => case op_field_2 is when "000" | "001" | "010" => cmp; when "011" | "111" => cmpa; when others => if op_field_3 = "001" then cmpm; else eor; end if; end case; when "1100" => var.dummy := bits_to_int(op_field_2 & op_field_3); case var.dummy is when 24 to 31 => mulu; when 56 to 63 => muls; when 32 to 33 => abcd; when 40 => exgd; when 41 => exga; when 49 => exgm; when others => andd; end case; when "1101" => if op_field_2bc = "11" then adda; else if op_field_2a & op_field_3ab = "100" then addx; else add; end if; end if; when "1110" => if op_field_2bc = "11" then case op_field_1 is when "000" => asm; when "001" => lsm; when "010" => roxm; when "011" => rom; when others =>n := '1'; end case; else case op_field_3bc is when "00" => asr; when "01" => lsr; when "10" => roxr; when "11" => ror; end case; end if; when others =>n := '1'; end case; exception_check; end loop; end process main; end MC68000;