📄 m68k.vhd
字号:
--------------------------------------------------------------------------
--------------------------------------------------------------------------
-- 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 + -