OpenCores
URL https://opencores.org/ocsvn/vhdl_cpu_emulator/vhdl_cpu_emulator/trunk

Subversion Repositories vhdl_cpu_emulator

[/] [vhdl_cpu_emulator/] [trunk/] [cpu_sim.vhd] - Diff between revs 2 and 3

Show entire file | Details | Blame | View Log

Rev 2 Rev 3
Line 1... Line 1...
 
--Mango DSP Ltd. Copyright (C) 2006
 
--Creator: Nachum Kanovsky
 
 
 
library ieee;
 
use ieee.std_logic_1164.all;
 
use work.design_top_constants.all;
 
use std.textio.all;
 
use ieee.std_logic_unsigned.all;
 
use ieee.numeric_std.all;
 
 
 
entity cpu_sim is
 
  port(
 
    fname    : in    filename;
 
    clk      : out std_logic;
 
    rstN     : out   std_logic;
 
    cpu_cs1  : out   std_logic;
 
    cpu_cs2  : out   std_logic;
 
    cpu_cs3  : out   std_logic;
 
    cpu_we   : out   std_logic;
 
    cpu_a    : out std_logic_vector(4 downto 0);
 
    cpu_d    : inout std_logic_vector(7 downto 0);
 
    cpu_irq4 : in    std_logic;
 
    cpu_irq7 : in    std_logic
 
    );
 
end;
 
 
 
architecture cpu_sim_simple of cpu_sim is
 
  signal sig_clk : std_logic := '0';
 
  shared variable tclk : time    := 0 ns;
 
  shared variable rl   : integer := 1;
 
 
 
  function to_lower (
 
    constant c : character)
 
    return character is
 
  begin  -- to_lower
 
    if c >= 'A' and c <= 'Z' then
 
      return character'val(character'pos(c) - character'pos('A') + character'pos('a'));
 
    else
 
      return c;
 
    end if;
 
  end to_lower;
 
 
 
  procedure eat_white (
 
    variable l : inout line) is
 
    variable old_l : line := l;
 
    variable p     : integer;
 
  begin
 
    if l = null then
 
      return;
 
    end if;
 
    if l'length = 0 then
 
      --string is empty
 
      deallocate(l);
 
      return;
 
    end if;
 
    p := l'left;
 
    while l'length > p - l'left and (l(p) = ' ' or l(p) = HT) loop
 
      p := p + 1;
 
    end loop;
 
    if p = l'left then
 
      --no whitespace
 
      return;
 
    elsif l'length <= p - l'left then
 
      --only whitespace - p passed the whole string
 
      deallocate(l);
 
    else
 
      l := new string'(old_l(p to old_l'right));
 
      deallocate(old_l);
 
    end if;
 
  end eat_white;
 
 
 
  procedure shrink_line (
 
    variable l : inout line;
 
    variable p : inout integer) is
 
    variable old_l : line := l;
 
  begin
 
    assert l /= null report "shrink_line l equals null" severity failure;
 
    if p = 0 then
 
      return;
 
    elsif p = l'length then
 
      deallocate(l);
 
    else
 
      l := new string'(old_l(old_l'left + p + 1 to old_l'right));
 
      deallocate(old_l);
 
    end if;
 
  end shrink_line;
 
 
 
  procedure read_word (
 
    l     : inout line;
 
    value : inout line) is
 
    variable size : integer := 0;
 
    variable p    : integer;
 
  begin
 
    if value /= null then
 
      deallocate(value);
 
    end if;
 
    eat_white(l);
 
    if l = null then
 
      return;
 
    end if;
 
    p := l'left;
 
    while l'length > p - l'left and (l(p) /= ' ' and l(p) /= HT) loop
 
      l(p) := to_lower(l(p));
 
      p    := p + 1;
 
    end loop;
 
    p     := p - 1;
 
    value := new string'(l(l'left to p));
 
    p     := p + 1 - l'left;
 
    shrink_line(l, p);
 
  end read_word;
 
 
 
  procedure get_line(
 
    file f     :       text;
 
    variable l : inout line) is
 
  begin
 
    if l /= null then
 
      deallocate(l);
 
    end if;
 
    loop
 
      if endfile(f) then
 
        return;
 
      end if;
 
      readline(f, l);
 
      eat_white(l);
 
      if l /= null and l(l'left) /= '#' then
 
        return;
 
      else
 
        deallocate(l);
 
      end if;
 
    end loop;
 
  end get_line;
 
 
 
  type dfile is record
 
    fn : line;
 
    ln : integer;
 
  end record;
 
  type dfile_access is access dfile;
 
 
 
  procedure readline(
 
    variable dfa : inout dfile_access;
 
    l            : inout line) is
 
    file fl    : text;
 
    variable c : integer := 0;
 
  begin
 
    file_open(fl, dfa.fn.all, read_mode);
 
    if l /= null then
 
      deallocate(l);
 
    end if;
 
    while c /= dfa.ln loop
 
      if endfile(fl) then
 
        if l /= null then
 
          deallocate(l);
 
        end if;
 
        file_close(fl);
 
        return;
 
      end if;
 
      readline(fl, l);
 
      c := c + 1;
 
    end loop;
 
    if endfile(fl) then
 
      if l /= null then
 
        deallocate(l);
 
      end if;
 
      file_close(fl);
 
      return;
 
    end if;
 
    readline(fl, l);
 
    file_close(fl);
 
    dfa.ln := dfa.ln + 1;
 
  end readline;
 
 
 
  --writeline deallocates the line
 
  procedure write(
 
    variable fn : in    line;
 
    variable l  : inout line) is
 
    file fl        : text;
 
    file fl_tmp    : text;
 
    variable l_tmp : line;
 
  begin
 
    file_open(fl_tmp, "tmp.txt", write_mode);
 
    file_open(fl, fn.all, read_mode);
 
    while not endfile(fl) loop
 
      readline(fl, l_tmp);
 
      writeline(fl_tmp, l_tmp);
 
    end loop;
 
    l_tmp := new string'(l(l'left to l'right));
 
    writeline(fl_tmp, l_tmp);
 
    file_close(fl_tmp);
 
    file_close(fl);
 
    file_open(fl_tmp, "tmp.txt", read_mode);
 
    file_open(fl, fn.all, write_mode);
 
    while not endfile(fl_tmp) loop
 
      readline(fl_tmp, l_tmp);
 
      writeline(fl, l_tmp);
 
    end loop;
 
    file_close(fl_tmp);
 
    file_close(fl);
 
  end write;
 
 
 
  procedure write(
 
    variable fn : in line;
 
    variable sl : in std_logic) is
 
    file fl        : text;
 
    file fl_tmp    : text;
 
    variable b     : bit;
 
    variable l_tmp : line;
 
  begin
 
    file_open(fl_tmp, "tmp.txt", write_mode);
 
    file_open(fl, fn.all, read_mode);
 
    while not endfile(fl) loop
 
      readline(fl, l_tmp);
 
      writeline(fl_tmp, l_tmp);
 
    end loop;
 
    if sl = '1' then
 
      b := '1';
 
    else
 
      b := '0';
 
    end if;
 
    write(l_tmp, b);
 
    writeline(fl, l_tmp);
 
    file_close(fl_tmp);
 
    file_close(fl);
 
    file_open(fl_tmp, "tmp.txt", read_mode);
 
    file_open(fl, fn.all, write_mode);
 
    while not endfile(fl_tmp) loop
 
      readline(fl_tmp, l_tmp);
 
      writeline(fl, l_tmp);
 
    end loop;
 
    file_close(fl_tmp);
 
    file_close(fl);
 
  end write;
 
 
 
  procedure write(
 
    variable fn   : in line;
 
    variable slv8 : in std_logic_vector(7 downto 0)) is
 
    file fl        : text;
 
    file fl_tmp    : text;
 
    variable l_tmp : line;
 
  begin
 
    file_open(fl_tmp, "tmp.txt", write_mode);
 
    file_open(fl, fn.all, read_mode);
 
    while not endfile(fl) loop
 
      readline(fl, l_tmp);
 
      writeline(fl_tmp, l_tmp);
 
    end loop;
 
    write(l_tmp, to_bitVector(slv8));
 
    writeline(fl_tmp, l_tmp);
 
    file_close(fl_tmp);
 
    file_close(fl);
 
    file_open(fl_tmp, "tmp.txt", read_mode);
 
    file_open(fl, fn.all, write_mode);
 
    while not endfile(fl_tmp) loop
 
      readline(fl_tmp, l_tmp);
 
      writeline(fl, l_tmp);
 
    end loop;
 
    file_close(fl_tmp);
 
    file_close(fl);
 
  end write;
 
 
 
  procedure get_line(
 
    variable dfa : inout dfile_access;
 
    variable l   : inout line) is
 
    variable l_temp : line;
 
  begin
 
    if l /= null then
 
      deallocate(l);
 
    end if;
 
    loop
 
      readline(dfa, l_temp);
 
      if l_temp = null then
 
        l := null;
 
        return;
 
      end if;
 
      eat_white(l_temp);
 
      if l_temp /= null and l_temp(l_temp'left) /= '#' then
 
        l := l_temp;
 
        return;
 
      end if;
 
    end loop;
 
  end get_line;
 
 
 
  type wait_commands is (wt_done, wt_time, wt_irq4, wt_irq7);
 
 
 
  type waiter is record
 
    cmd    : wait_commands;
 
    tm_end : time;
 
    v      : std_logic;
 
  end record;
 
  type waiter_access is access waiter;
 
 
 
  procedure check_wait(
 
    variable w : inout waiter) is
 
  begin
 
    case w.cmd is
 
      when wt_time =>
 
        if now >= w.tm_end then
 
          w.cmd := wt_done;
 
        end if;
 
      when wt_irq4 =>
 
        if cpu_irq4 = w.v then
 
          w.cmd := wt_done;
 
        end if;
 
      when wt_irq7 =>
 
        if cpu_irq7 = w.v then
 
          w.cmd := wt_done;
 
        end if;
 
      when others => null;
 
    end case;
 
  end check_wait;
 
 
 
  type var_types is (vt_string, vt_bit, vt_vector8);
 
  type var;
 
  type var_access is access var;
 
  type var_accessx16 is array (15 downto 0) of var_access;
 
  type var is record
 
    n    : line;
 
    vt   : var_types;
 
    s    : line;
 
    sl   : std_logic;
 
    slv8 : std_logic_vector(7 downto 0);
 
  end record;
 
  type vars;
 
  type vars_access is access vars;
 
  type vars is record
 
    va16     : var_accessx16;
 
    next_vsa : vars_access;
 
  end record;
 
 
 
  procedure get_var(
 
    variable n   : in  line;
 
    variable vsa : in  vars_access;
 
    variable va  : out var_access) is
 
  begin
 
    if vsa = null then
 
      return;
 
    end if;
 
    va := null;
 
    for i in vsa.va16'range loop
 
      if vsa.va16(i) /= null and vsa.va16(i).n.all = n.all then
 
        va := vsa.va16(i);
 
        return;
 
      end if;
 
    end loop;
 
    get_var(n, vsa.next_vsa, va);
 
  end get_var;
 
 
 
  procedure add_var(
 
    variable vsa : inout vars_access;
 
    variable n   : in    line;
 
    variable vt  : in    var_types) is
 
    variable vsa_temp : vars_access;
 
    variable v_temp   : var_access;
 
  begin
 
    vsa_temp     := vsa.next_vsa;
 
    vsa.next_vsa := null;
 
    get_var(n, vsa, v_temp);
 
    vsa.next_vsa := vsa_temp;
 
    vsa_temp     := null;
 
    if v_temp /= null then
 
      return;
 
    end if;
 
    for i in vsa.va16'range loop
 
      if vsa.va16(i) = null then
 
        vsa.va16(i)    := new var;
 
        vsa.va16(i).n  := new string'(n(n'left to n'right));
 
        vsa.va16(i).vt := vt;
 
        return;
 
      end if;
 
    end loop;
 
    report "too many variables" severity failure;
 
  end add_var;
 
 
 
  procedure add_var(
 
    variable vsa : inout vars_access;
 
    variable n   : in    line;
 
    variable s   : in    line) is
 
    variable v_temp : var_access;
 
    variable vt     : var_types;
 
  begin
 
    vt       := vt_string;
 
    add_var(vsa, n, vt);
 
    get_var(n, vsa, v_temp);
 
    v_temp.s := new string'(s(s'left to s'right));
 
  end add_var;
 
 
 
  procedure add_var(
 
    variable vsa : inout vars_access;
 
    variable n   : in    line;
 
    variable sl  : in    std_logic) is
 
    variable v_temp : var_access;
 
    variable vt     : var_types;
 
  begin
 
    vt        := vt_string;
 
    add_var(vsa, n, vt);
 
    get_var(n, vsa, v_temp);
 
    v_temp.sl := sl;
 
  end add_var;
 
 
 
  procedure add_var(
 
    variable vsa  : inout vars_access;
 
    variable n    : in    line;
 
    variable slv8 : in    std_logic_vector(7 downto 0)) is
 
    variable v_temp : var_access;
 
    variable vt     : var_types;
 
  begin
 
    vt          := vt_string;
 
    add_var(vsa, n, vt);
 
    get_var(n, vsa, v_temp);
 
    v_temp.slv8 := slv8;
 
  end add_var;
 
 
 
  type thread_states is (st_ready, st_done);
 
  type thread;
 
  type thread_access is access thread;
 
  type thread is record
 
    dfa      : dfile_access;
 
    ln_start : integer;
 
    st       : thread_states;
 
    w        : waiter_access;
 
    vsa      : vars_access;
 
    next_tha : thread_access;
 
  end record;
 
 
 
  type tholder;
 
  type tholder_access is access tholder;
 
  type tholder is record
 
    th : thread_access;
 
    n  : tholder_access;
 
    p  : tholder_access;
 
  end record;
 
 
 
  procedure init_thread (
 
    variable tha : inout thread_access;
 
    variable dfa : in    dfile_access;
 
    variable ln  : in    integer;
 
    variable w   : in    waiter_access;
 
    variable vsa : in    vars_access) is
 
    variable int : integer;
 
  begin
 
    tha.dfa          := dfa;
 
    tha.ln_start     := ln;
 
    tha.st           := st_ready;
 
    tha.w            := w;
 
    tha.vsa          := new vars;
 
    tha.vsa.next_vsa := vsa;
 
    tha.w.cmd        := wt_done;
 
  end init_thread;
 
 
 
  procedure declare_var(
 
    variable l_type    : inout line;
 
    variable l_varname : inout line;
 
    variable vsa       : inout vars_access) is
 
    variable vt : var_types;
 
  begin
 
    assert l_type /= null and l_varname /= null report "declare_var bad parameters" severity failure;
 
    if l_type.all = "bit" then
 
      vt := vt_bit;
 
      add_var(vsa, l_varname, vt);
 
    elsif l_type.all = "vector8" then
 
      vt := vt_vector8;
 
      add_var(vsa, l_varname, vt);
 
    elsif l_type.all = "string" then
 
      vt := vt_string;
 
      add_var(vsa, l_varname, vt);
 
    else
 
      report "l_type is not bit, vector8, or string" severity failure;
 
    end if;
 
  end declare_var;
 
 
 
  procedure var_test(
 
    variable l_left  : inout line;
 
    variable l_op    : inout line;
 
    variable l_right : inout line;
 
    variable bl_good : inout boolean;
 
    variable vsa     : inout vars_access) is
 
    variable va_left  : var_access;
 
    variable va_right : var_access;
 
    variable sl       : std_logic;
 
    variable slv8     : std_logic_vector(7 downto 0);
 
    variable b        : bit;
 
    variable bv8      : bit_vector(7 downto 0);
 
    variable s        : line;
 
  begin
 
    assert l_left /= null and l_op /= null and l_right /= null report "var_test invalid null parameters" severity failure;
 
    get_var(l_left, vsa, va_left);
 
    assert va_left /= null report "var_test left variable not found" severity failure;
 
    get_var(l_right, vsa, va_right);
 
    if va_right /= null then
 
      assert va_left.vt = va_right.vt report "var_test var types not the same" severity failure;
 
      case va_right.vt is
 
        when vt_bit =>
 
          sl := va_right.sl;
 
        when vt_vector8 =>
 
          slv8 := va_right.slv8;
 
        when vt_string =>
 
          s := va_right.s;
 
      end case;
 
    else
 
      case va_left.vt is
 
        when vt_bit =>
 
          read(l_right, b, bl_good);
 
          assert bl_good = true report "var_test last parameter failed read" severity failure;
 
          if b = '1' then
 
            sl := '1';
 
          else
 
            sl := '0';
 
          end if;
 
        when vt_vector8 =>
 
          read(l_right, bv8, bl_good);
 
          assert bl_good = true report "var_test last parameter failed read" severity failure;
 
          slv8 := to_stdlogicvector(bv8);
 
        when vt_string =>
 
          s := l_right;
 
      end case;
 
    end if;
 
    bl_good := false;
 
    case va_left.vt is
 
      when vt_bit =>
 
        assert l_op.all = "==" or l_op.all = ">" or l_op.all = "<" or l_op.all = "&" or l_op.all = "|" report "var_test invalid operation for bit, use ==,>,<,&,|" severity failure;
 
        if l_op.all = "==" then
 
          if va_left.sl = sl then
 
            bl_good := true;
 
            return;
 
          end if;
 
        elsif l_op.all = ">" then
 
          if va_left.sl > sl then
 
            bl_good := true;
 
            return;
 
          end if;
 
        elsif l_op.all = "<" then
 
          if va_left.sl < sl then
 
            bl_good := true;
 
            return;
 
          end if;
 
        elsif l_op.all = "&" then
 
          if (va_left.sl and sl) /= '0' then
 
            bl_good := true;
 
            return;
 
          end if;
 
        elsif l_op.all = "|" then
 
          if (va_left.sl or sl) /= '0' then
 
            bl_good := true;
 
            return;
 
          end if;
 
        end if;
 
      when vt_vector8 =>
 
        assert l_op.all = "==" or l_op.all = ">" or l_op.all = "<" or l_op.all = "&" or l_op.all = "|" report "var_test invalid operation for vector8, use ==,>,<,&,|" severity failure;
 
        if l_op.all = "==" then
 
          if va_left.slv8 = slv8 then
 
            bl_good := true;
 
            return;
 
          end if;
 
        elsif l_op.all = ">" then
 
          if va_left.slv8 > slv8 then
 
            bl_good := true;
 
            return;
 
          end if;
 
        elsif l_op.all = "<" then
 
          if va_left.slv8 < slv8 then
 
            bl_good := true;
 
            return;
 
          end if;
 
        elsif l_op.all = "&" then
 
          if (va_left.slv8 and slv8) /= "00000000" then
 
            bl_good := true;
 
            return;
 
          end if;
 
        elsif l_op.all = "|" then
 
          if (va_left.slv8 or slv8) /= "00000000" then
 
            bl_good := true;
 
            return;
 
          end if;
 
        end if;
 
      when vt_string =>
 
        assert l_op.all = "==" report "var_test string has only == operation" severity failure;
 
        if va_left.s = s then
 
          bl_good := true;
 
          return;
 
        end if;
 
      when others => null;
 
    end case;
 
  end var_test;
 
 
 
--variables are deallocated in this function
 
  procedure var_op (
 
    variable l_left  : inout line;
 
    variable l_op    : inout line;
 
    variable l_right : inout line;
 
    variable vsa     : inout vars_access) is
 
    variable va_left  : var_access;
 
    variable va_right : var_access;
 
    variable slv8     : std_logic_vector(7 downto 0);
 
    variable slv16    : std_logic_vector(15 downto 0);
 
    variable b        : bit;
 
    variable bv8      : bit_vector(7 downto 0);
 
    variable bl_good  : boolean;
 
  begin
 
    assert l_left /= null and l_op /= null and l_right /= null report "l_left or l_op or l_right are null" severity failure;
 
    if l_left.all = "bit" or l_left.all = "vector8" or l_left.all = "string" then
 
      declare_var(l_left, l_op, vsa);
 
      l_left := l_op;
 
      l_op   := null;
 
      read_word(l_right, l_op);
 
    end if;
 
    get_var(l_left, vsa, va_left);
 
    assert va_left /= null report "variable not found" severity failure;
 
    case va_left.vt is
 
      when vt_string =>
 
        assert l_op.all = "=" report "illegal op, string has only = operation" severity failure;
 
        if va_left.s /= null then
 
          deallocate(va_left.s);
 
        end if;
 
        get_var(l_right, vsa, va_right);
 
        if va_right /= null then
 
          va_left.s := new string'(va_right.s(va_right.s'left to va_right.s'right));
 
        else
 
          read_word(l_right, va_left.s);
 
        end if;
 
      when vt_bit =>
 
        assert l_op.all = "=" report "illegal op, bit has only = operation" severity failure;
 
        get_var(l_right, vsa, va_right);
 
        if va_right /= null then
 
          assert va_right.vt = vt_bit report "non bit variable being op'ed with bit variable" severity failure;
 
          va_left.sl := va_right.sl;
 
        else
 
          read(l_right, b, bl_good);
 
          if bl_good = true then
 
            if b = '1' then
 
              va_left.sl := '1';
 
            else
 
              va_left.sl := '0';
 
            end if;
 
          else
 
            report "bit operation missing bit value" severity failure;
 
          end if;
 
        end if;
 
      when vt_vector8 =>
 
        get_var(l_right, vsa, va_right);
 
        if va_right /= null then
 
          assert va_right.vt = vt_vector8 report "non vector8 variable being op'ed with vector8 variable" severity failure;
 
          slv8 := va_right.slv8;
 
        else
 
          read(l_right, bv8);
 
          slv8 := to_stdlogicvector(bv8);
 
        end if;
 
        if l_op.all = "=" then
 
          va_left.slv8 := slv8;
 
        elsif l_op.all = "+=" then
 
          va_left.slv8 := va_left.slv8 + slv8;
 
        elsif l_op.all = "-=" then
 
          va_left.slv8 := va_left.slv8 - slv8;
 
        elsif l_op.all = "*=" then
 
          slv16        := va_left.slv8 * slv8;
 
          va_left.slv8 := slv16(7 downto 0);
 
        elsif l_op.all = "&=" then
 
          va_left.slv8 := va_left.slv8 and slv8;
 
        elsif l_op.all = "|=" then
 
          va_left.slv8 := va_left.slv8 or slv8;
 
        else
 
          report "illegal op, vector8 has only =, +, -, &, | operations" severity failure;
 
        end if;
 
    end case;
 
    deallocate(l_left);
 
    deallocate(l_op);
 
    deallocate(l_right);
 
  end var_op;
 
 
 
  procedure clear(
 
    variable fn : inout line) is
 
    file fl : text;
 
  begin
 
    file_open(fl, fn.all, write_mode);
 
    file_close(fl);
 
  end clear;
 
 
 
  procedure find_match (
 
    variable dfa     : inout dfile_access;
 
    constant s_open  : in    string;
 
    constant s_close : in    string) is
 
    variable l   : line;
 
    variable cmd : line;
 
  begin
 
    get_line(dfa, l);
 
    read_word(l, cmd);
 
    while cmd.all /= s_close loop
 
      if cmd.all = s_open then
 
        find_match(dfa, s_open, s_close);
 
      end if;
 
      get_line(dfa, l);
 
      read_word(l, cmd);
 
    end loop;
 
  end find_match;
 
 
 
  procedure find_match (
 
    variable dfa     : inout dfile_access;
 
    constant s_open  : in    string;
 
    constant s_other  : in    string;
 
    constant s_close : in    string) is
 
    variable l   : line;
 
    variable cmd : line;
 
  begin
 
    get_line(dfa, l);
 
    read_word(l, cmd);
 
    while cmd.all /= s_close and cmd.all /= s_other loop
 
      if cmd.all = s_open then
 
        find_match(dfa, s_open, s_close);
 
      end if;
 
      get_line(dfa, l);
 
      read_word(l, cmd);
 
    end loop;
 
  end find_match;
 
 
 
  procedure read_dma (
 
    variable l       : inout line;
 
    variable vsa     : inout vars_access;
 
    signal   cpu_cs1 : out   std_logic;
 
    signal   cpu_we  : out   std_logic;
 
    signal   cpu_a   : out std_logic_vector(4 downto 0);
 
    signal   cpu_d   : inout std_logic_vector(7 downto 0)) is
 
    variable l_tmp : line;
 
    variable va : var_access;
 
    variable addr : std_logic_vector(7 downto 0);
 
    variable size : integer;
 
    variable incr : integer;
 
    variable bl_good : boolean;
 
    variable bv8 : bit_vector(7 downto 0);
 
    variable filename : line;
 
    variable slv8 : std_logic_vector(7 downto 0);
 
  begin
 
    read_word(l, l_tmp);
 
    assert l_tmp /= null report "read_dma parameter missing" severity failure;
 
    get_var(l_tmp, vsa, va);
 
    if va = null then
 
      read(l_tmp, bv8, bl_good);
 
      assert bl_good report "read_dma address invalid" severity failure;
 
      addr := to_stdlogicvector(bv8);
 
    else
 
      assert va.vt = vt_vector8 report "read_dma address variable not found" severity failure;
 
      addr := va.slv8;
 
    end if;
 
    read_word(l, l_tmp);
 
    assert l_tmp /= null report "read_dma parameter missing" severity failure;
 
    get_var(l_tmp, vsa, va);
 
    if va = null then
 
      read(l_tmp, bv8, bl_good);
 
      assert bl_good report "read_dma size invalid" severity failure;
 
      size := to_integer(unsigned(to_stdlogicvector(bv8)));
 
    else
 
      assert va /= null and va.vt = vt_vector8 report "read_dma size variable not found" severity failure;
 
      size := to_integer(unsigned(va.slv8));
 
    end if;
 
    read_word(l, l_tmp);
 
    assert l_tmp /= null report "read_dma parameter missing" severity failure;
 
    get_var(l_tmp, vsa, va);
 
    if va = null then
 
      read(l_tmp, bv8, bl_good);
 
      assert bl_good report "read_dma incr invalid" severity failure;
 
      incr := to_integer(unsigned(to_stdlogicvector(bv8)));
 
    else
 
      assert va /= null and va.vt = vt_vector8 report "read_dma incr variable not found" severity failure;
 
      incr := to_integer(unsigned(va.slv8));
 
    end if;
 
    read_word(l, l_tmp);
 
    assert l_tmp /= null report "read_dma parameter missing" severity failure;
 
    filename := l_tmp;
 
    l_tmp := null;
 
 
 
    for i in 0 to size - 1 loop
 
      if i < (size + rl) then
 
        cpu_cs1 <= '1';
 
        cpu_a <= addr(cpu_a'range);
 
        addr := addr + incr;
 
      end if;
 
      if i > rl then
 
        slv8 := cpu_d;
 
        write(filename, slv8);
 
      end if;
 
      wait for 1 ps;
 
      wait until rising_edge(sig_clk);
 
    end loop;
 
    cpu_cs1 <= '0';
 
    cpu_a   <= (others => '0');
 
    for i in 0 to rl - 1 loop
 
      if (size + i) > rl then
 
        slv8 := cpu_d;
 
        write(filename, slv8);
 
      end if;
 
      wait for 1 ps;
 
      wait until rising_edge(sig_clk);
 
    end loop;
 
    slv8 := cpu_d;
 
    write(filename, slv8);
 
--        cpu_cs1 <= '1';
 
--        wait for 1 ps;
 
--        wait until rising_edge(sig_clk);
 
--        cpu_cs1 <= '0';
 
--        cpu_a   <= (others => '0');
 
--        for i in 1 to rl loop
 
--          --waiting for data to get back
 
--          wait for 1 ps;
 
--          wait until rising_edge(sig_clk);
 
--        end loop;  -- i
 
--        read_word(l, l_first);
 
--        if l_first = null then
 
--          exit;
 
--        end if;
 
--        get_var(l_first, tha.vsa, va);
 
--        assert va /= null and va.vt = vt_vector8 report "illegal address for read" severity failure;
 
--        va.slv8 := cpu_d;
 
--        va      := null;
 
  end read_dma;
 
 
 
  procedure process_thread (
 
    variable tha     : inout thread_access;
 
    signal   cpu_cs1 : out   std_logic;
 
    signal   cpu_we  : out   std_logic;
 
    signal   cpu_a   : out std_logic_vector(4 downto 0);
 
    signal   cpu_d   : inout std_logic_vector(7 downto 0)) is
 
    variable va       : var_access;
 
    variable l        : line;
 
    variable tm       : time;
 
    variable b        : bit;
 
    variable l_first  : line;
 
    variable l_second : line;
 
    variable bl_good  : boolean;
 
    variable bv8      : bit_vector(7 downto 0);
 
  begin
 
    while tha.st = st_ready and tha.w.all.cmd = wt_done loop
 
      if tha.next_tha /= null then
 
        if tha.next_tha.st = st_done then
 
          find_match(tha.dfa, "while", "while_end");
 
          deallocate(tha.next_tha);
 
        else
 
          process_thread(tha.next_tha, cpu_cs1, cpu_we, cpu_a, cpu_d);
 
          exit;
 
        end if;
 
      end if;
 
      if tha.st = st_ready then
 
        get_line(tha.dfa, l);
 
        read_word(l, l_first);
 
      end if;
 
      tha.st := st_ready;
 
      if l_first = null then
 
        tha.st := st_done;
 
      elsif l_first.all = "wait" then
 
        read(l, tm);
 
        tha.w.cmd    := wt_time;
 
        tha.w.tm_end := tm + now;
 
        check_wait(tha.w.all);
 
      elsif l_first.all = "wait_interrupt4" then
 
        tha.w.cmd := wt_irq4;
 
        read(l, b, bl_good);
 
        if bl_good then
 
          if b = '1' then
 
            tha.w.v := '1';
 
          else
 
            tha.w.v := '0';
 
          end if;
 
        else
 
          tha.w.v := '1';
 
        end if;
 
        check_wait(tha.w.all);
 
      elsif l_first.all = "while" then
 
        tha.next_tha := new thread;
 
        init_thread(tha.next_tha, tha.dfa, tha.dfa.ln, tha.w, tha.vsa);
 
      elsif l_first.all = "while_exit" then
 
        tha.st := st_done;
 
      elsif l_first.all = "while_end" then
 
        tha.dfa.ln := tha.ln_start;
 
      elsif l_first.all = "if" then
 
        read_word(l, l_first);
 
        read_word(l, l_second);
 
        var_test(l_first, l_second, l, bl_good, tha.vsa);
 
        if bl_good = false then
 
          find_match(tha.dfa, "if", "if_else", "if_end");
 
        end if;
 
      elsif l_first.all = "if_else" then
 
        find_match(tha.dfa, "if", "if_end");
 
      elsif l_first.all = "if_end" then
 
      elsif l_first.all = "clear" then
 
        read_word(l, l_first);
 
        assert l_first /= null report "clear without file or variable name" severity failure;
 
        get_var(l_first, tha.vsa, va);
 
        if va /= null then
 
          assert va.vt = vt_string report "non string variable name" severity failure;
 
          clear(va.s);
 
        else
 
          clear(l_first);
 
        end if;
 
        deallocate(l_first);
 
        va := null;
 
      elsif l_first.all = "read" then
 
        cpu_cs1 <= '1';
 
        read_word(l, l_first);
 
        assert l_first /= null report "read parameter missing" severity failure;
 
        get_var(l_first, tha.vsa, va);
 
        assert va = null or va.vt = vt_vector8 report "illegal address for read" severity failure;
 
        if va = null then
 
          read(l_first, bv8);
 
          cpu_a <= to_stdlogicvector(bv8)(cpu_a'left downto 0);
 
        else
 
          cpu_a <= va.slv8(cpu_a'left downto 0);
 
          va    := null;
 
        end if;
 
        --waiting for request to get to cpu block
 
        wait for 1 ps;
 
        wait until rising_edge(sig_clk);
 
        cpu_cs1 <= '0';
 
        cpu_a   <= (others => '0');
 
        for i in 1 to rl loop
 
          --waiting for data to get back
 
          wait for 1 ps;
 
          wait until rising_edge(sig_clk);
 
        end loop;  -- i
 
        read_word(l, l_first);
 
        if l_first = null then
 
          exit;
 
        end if;
 
        get_var(l_first, tha.vsa, va);
 
        assert va /= null and va.vt = vt_vector8 report "illegal address for read" severity failure;
 
        va.slv8 := cpu_d;
 
        va      := null;
 
      elsif l_first.all = "write" then
 
        cpu_cs1 <= '1';
 
        cpu_we  <= '1';
 
        read_word(l, l_first);
 
        assert l_first /= null report "write parameter missing" severity failure;
 
        get_var(l_first, tha.vsa, va);
 
        assert va = null or va.vt = vt_vector8 report "illegal address for write" severity failure;
 
        if va = null then
 
          read(l_first, bv8);
 
          cpu_a <= to_stdlogicvector(bv8)(cpu_a'left downto 0);
 
        else
 
          cpu_a <= va.slv8(cpu_a'left downto 0);
 
          va    := null;
 
        end if;
 
        deallocate(l_first);
 
        read_word(l, l_first);
 
        assert l_first /= null report "write parameter missing" severity failure;
 
        get_var(l_first, tha.vsa, va);
 
        assert va = null or va.vt = vt_vector8 report "illegal data for write" severity failure;
 
        if va = null then
 
          read(l_first, bv8);
 
          cpu_d <= to_stdlogicvector(bv8)(cpu_d'left downto 0);
 
        else
 
          cpu_d <= va.slv8(cpu_d'left downto 0);
 
          va    := null;
 
        end if;
 
        deallocate(l_first);
 
        wait for 1 ps;
 
        wait until rising_edge(sig_clk);
 
        cpu_cs1 <= '0';
 
        cpu_we  <= '0';
 
        cpu_a   <= (others => '0');
 
        cpu_d   <= (others => 'Z');
 
      elsif l_first.all = "read_dma" then
 
        read_dma(l, tha.vsa, cpu_cs1, cpu_we, cpu_a, cpu_d);
 
      elsif l_first.all = "write" then
 
--        write_dma(l, tha.vsa, cpu_cs1, cpu_we, cpu_a, cpu_d);
 
      elsif l_first.all = "print" then
 
        read_word(l, l_first);
 
        assert l_first /= null report "no file or variable name for print" severity failure;
 
        get_var(l_first, tha.vsa, va);
 
        if va /= null then
 
          deallocate(l_first);
 
          l_first := va.s;
 
          va      := null;
 
        end if;
 
        read_word(l, l_second);
 
        assert l_second /= null report "no variable name for print" severity failure;
 
        get_var(l_second, tha.vsa, va);
 
        l_second := null;
 
        assert va /= null report "invalid variable for print" severity failure;
 
        if va.vt = vt_string then
 
          write(l_first, va.s);
 
        elsif va.vt = vt_bit then
 
          write(l_first, va.sl);
 
        elsif va.vt = vt_vector8 then
 
          write(l_first, va.slv8);
 
        end if;
 
        l_first := null;
 
        va      := null;
 
      elsif l_first.all = "breakpoint" then
 
        deallocate(l_first);
 
      else
 
        read_word(l, l_second);
 
        var_op(l_first, l_second, l, tha.vsa);
 
      end if;
 
    end loop;
 
    deallocate(l);
 
    deallocate(l_first);
 
  end process_thread;
 
 
 
begin
 
  sig_clk <= not sig_clk after tclk;
 
  clk <= sig_clk;
 
  process
 
    file fl               : text;
 
    variable l            : line;
 
    variable l_params     : line;
 
    variable tm           : time;
 
    variable bl_alldone   : boolean;
 
    variable vsa          : vars_access;
 
    variable l_first      : line;
 
    variable l_second     : line;
 
    variable l_third      : line;
 
    variable wa           : waiter_access;
 
    variable dfa          : dfile_access;
 
    variable tholda_start : tholder_access;
 
    variable tholda       : tholder_access;
 
    variable tholda_prev  : tholder_access;
 
  begin
 
    rstN    <= '0';
 
    cpu_cs1 <= '0';
 
    cpu_cs2 <= '0';
 
    cpu_cs3 <= '0';
 
    cpu_we  <= '0';
 
    cpu_a   <= (others => '0');
 
    cpu_d   <= (others => 'Z');
 
    file_open(fl, fname, read_mode);
 
    vsa     := new vars;
 
    loop
 
      get_line(fl, l);
 
      read_word(l, l_first);
 
      if l_first = null then
 
        exit;
 
      elsif l_first.all = "clock" then
 
        read(l, tm);
 
        tclk := tm;
 
      elsif l_first.all = "reset" then
 
        read(l, tm);
 
        wait for tm;
 
        rstN <= '1';
 
      elsif l_first.all = "read_latency" then
 
        read(l, rl);
 
      elsif l_first.all = "thread" then
 
        tholda := new tholder;
 
        if tholda_start = null then
 
          tholda_start := tholda;
 
          tholda_prev  := tholda_start;
 
        else
 
          tholda_prev.n := tholda;
 
          tholda_prev   := tholda;
 
        end if;
 
        tholda.th := new thread;
 
        read_word(l, l_second);
 
        wa        := new waiter;
 
        dfa       := new dfile;
 
        dfa.fn    := l_second;
 
        l_second  := null;
 
        dfa.ln    := 0;
 
        init_thread(tholda.th, dfa, dfa.ln, wa, vsa);
 
        while l_first /= null and l_first.all /= "parameters" loop
 
          get_line(tholda.th.dfa, l_params);
 
          read_word(l_params, l_first);
 
        end loop;
 
        if l_first /= null and l_first.all = "parameters" then
 
          loop
 
            read_word(l_params, l_first);
 
            if l_first = null then
 
              exit;
 
            end if;
 
            assert l_first.all = "bit" or l_first.all = "vector8" or l_first.all = "string" report "illegal variable type in parameter list" severity failure;
 
            read_word(l_params, l_second);
 
            assert l_second /= null report "variable name missing in parameter list" severity failure;
 
            declare_var(l_first, l_second, tholda.th.vsa);
 
            deallocate(l_first);
 
            l_first  := l_second;
 
            l_second := new string'("=");
 
            read_word(l, l_third);
 
            assert l_third /= null report "variable value missing in thread spawn call" severity failure;
 
            var_op(l_first, l_second, l_third, tholda.th.vsa);
 
          end loop;
 
        else
 
          tholda.th.dfa.ln := 0;
 
        end if;
 
        tholda := tholda.n;
 
      else
 
        read_word(l, l_second);
 
        var_op(l_first, l_second, l, vsa);
 
      end if;
 
    end loop;
 
    wait for 1 ps;
 
    wait until rising_edge(sig_clk);
 
    loop
 
      bl_alldone := true;
 
      tholda     := tholda_start;
 
      while tholda /= null loop
 
        if tholda.th.w.cmd /= wt_done then
 
          check_wait(tholda.th.w.all);
 
          bl_alldone := false;
 
        end if;
 
        tholda := tholda.n;
 
      end loop;
 
      tholda      := tholda_start;
 
      tholda_prev := null;
 
      while tholda /= null loop
 
        if tholda.th.w.cmd = wt_done then
 
          process_thread(tholda.th, cpu_cs1, cpu_we, cpu_a, cpu_d);
 
          bl_alldone := false;
 
        end if;
 
        if tholda.th.st = st_done then
 
          if tholda_prev /= null then
 
            tholda_prev.n := tholda.n;
 
          else
 
            tholda_start := tholda.n;
 
          end if;
 
          deallocate(tholda.th.w);
 
          deallocate(tholda.th.vsa);
 
          deallocate(tholda.th.dfa);
 
          deallocate(tholda.th);
 
        end if;
 
        tholda_prev := tholda;
 
        tholda      := tholda.n;
 
      end loop;
 
      wait for 1 ps;
 
      wait until rising_edge(sig_clk);
 
      if bl_alldone then
 
        cpu_cs1 <= '0';
 
        cpu_we  <= '0';
 
        cpu_a   <= (others => '0');
 
        cpu_d   <= (others => 'Z');
 
        wait;
 
      end if;
 
    end loop;
 
  end process;
 
end cpu_sim_simple;
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.