dlx/dlx-instrumented.vhdl

    1 --------------------------------------------------------------------------
    2 --
    3 --  Copyright (C) 1993, Peter J. Ashenden
    4 --  Mail:       Dept. Computer Science
    5 --              University of Adelaide, SA 5005, Australia
    6 --  e-mail:     petera@cs.adelaide.edu.au
    7 --
    8 --  This program is free software; you can redistribute it and/or modify
    9 --  it under the terms of the GNU General Public License as published by
   10 --  the Free Software Foundation; either version 1, or (at your option)
   11 --  any later version.
   12 --
   13 --  This program is distributed in the hope that it will be useful,
   14 --  but WITHOUT ANY WARRANTY; without even the implied warranty of
   15 --  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16 --  GNU General Public License for more details.
   17 --
   18 --  You should have received a copy of the GNU General Public License
   19 --  along with this program; if not, write to the Free Software
   20 --  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   21 --
   22 --------------------------------------------------------------------------
   23 --
   24 --  $RCSfile: dlx-instrumented.vhdl,v $  $Revision: 1.1 $  $Date: 2000/05/08 14:36:48 $
   25 --
   26 --------------------------------------------------------------------------
   27 --
   28 --  Instrumented behavioural architecture for DLX, that generates
   29 --  a files of instruction execution frequencies for a program.
   30 --
   31 
   32 
   33 use work.dlx_instr.all,
   34     work.bv_arithmetic.all,
   35     std.textio.all;
   36 
   37 
   38 architecture instrumented of dlx is
   39 
   40 begin -- instrumented
   41 
   42   interpreter: process
   43 
   44     type reg_array is array (reg_index) of dlx_word;
   45 
   46     variable reg : reg_array;
   47     variable fp_reg : reg_array;
   48 
   49     variable PC : dlx_word;
   50     variable user_mode : boolean;
   51     variable overflow, div_by_zero : boolean;
   52 
   53     constant PC_incr : dlx_word := X"0000_0004";
   54 
   55     variable IR : dlx_word;
   56     alias IR_opcode : dlx_opcode is IR(0 to 5);
   57     alias IR_sp_func : dlx_sp_func is IR(26 to 31);
   58     alias IR_fp_func : dlx_fp_func is IR(27 to 31);
   59     alias IR_rs1 : dlx_reg_addr is IR(6 to 10);
   60     alias IR_rs2 : dlx_reg_addr is IR(11 to 15);
   61     alias IR_Itype_rd : dlx_reg_addr is IR(11 to 15);
   62     alias IR_Rtype_rd : dlx_reg_addr is IR(16 to 20);
   63     alias IR_immed16 : dlx_immed16 is IR(16 to 31);
   64     alias IR_immed26 : dlx_immed26 is IR(6 to 31);
   65 
   66     variable IR_opcode_num : dlx_opcode_num;
   67     variable IR_sp_func_num : dlx_sp_func_num;
   68     variable IR_fp_func_num : dlx_fp_func_num;
   69     variable rs1, rs2, Itype_rd, Rtype_rd : reg_index;
   70     variable mem_addr : dlx_address;
   71     variable mem_data : dlx_word;
   72 
   73     subtype ls_2_addr_bits is bit_vector(1 downto 0);
   74 
   75     file data : text is out "dlx_instruction_counts";
   76 
   77     variable L : line;
   78 
   79 
   80     ---------------------------------------------------------------------------
   81     --  instrumentation: array of counters, one per instruction
   82     ---------------------------------------------------------------------------
   83 
   84     type opcode_count_array is array (dlx_opcode_num) of natural;
   85     type sp_func_count_array is array (dlx_sp_func_num) of natural;
   86     type fp_func_count_array is array (dlx_fp_func_num) of natural;
   87 
   88     variable    op_count        : opcode_count_array := (others => 0);
   89     variable    sp_func_count   : sp_func_count_array := (others => 0);
   90     variable    fp_func_count   : fp_func_count_array := (others => 0);
   91 
   92     variable    instr_count     : natural := 0;
   93 
   94     ---------------------------------------------------------------------------
   95     --  instrumentation: procedure to dump counter values
   96     ---------------------------------------------------------------------------
   97 
   98     procedure instrumentation_dump is
   99       variable L : line;
  100     begin
  101       for op in dlx_opcode_num loop
  102         write(L, opcode_names(op));
  103         write(L, ' ');
  104         write(L, op_count(op));
  105         writeline(data, L);
  106       end loop;
  107       for sp_func in dlx_sp_func_num loop
  108         write(L, sp_func_names(sp_func));
  109         write(L, ' ');
  110         write(L, sp_func_count(sp_func));
  111         writeline(data, L);
  112       end loop;
  113       for fp_func in dlx_fp_func_num loop
  114         write(L, fp_func_names(fp_func));
  115         write(L, ' ');
  116         write(L, fp_func_count(fp_func));
  117         writeline(data, L);
  118       end loop;
  119     end instrumentation_dump;
  120 
  121     ---------------------------------------------------------------------------
  122 
  123 
  124     procedure write (address : in dlx_address;
  125                      data_width : in mem_width;
  126                      data : in dlx_word;
  127                      signal phi1, phi2 : in bit;    -- 2-phase non-overlapping clks
  128                      signal reset : in bit;         -- synchronous reset input
  129                      signal a : out dlx_address;    -- address bus output
  130                      signal d : inout dlx_word_bus; -- bidirectional data bus
  131                      signal width : out mem_width;  -- byte/halfword/word
  132                      signal write_enable : out bit; -- selects read/write cycle
  133                      signal mem_enable : out bit;   -- starts memory cycle
  134                      signal ifetch : out bit;       -- indicates instruction fetch
  135                      signal ready : in bit;         -- status from memory system
  136                      Tpd_clk_out : in time          -- clock to output delay
  137                     ) is
  138 
  139     begin
  140       wait until phi1 = '1';
  141       if reset = '1' then
  142         return;
  143       end if;
  144       a <= address after Tpd_clk_out;
  145       width <= data_width after Tpd_clk_out;
  146       d <= data after Tpd_clk_out;
  147       write_enable <= '1' after Tpd_clk_out;
  148       mem_enable <= '1' after Tpd_clk_out;
  149       ifetch <= '0' after Tpd_clk_out;
  150       loop
  151         wait until phi2 = '0';
  152         exit when ready = '1' or reset = '1';
  153       end loop;
  154       d <= null after Tpd_clk_out;
  155       write_enable <= '0' after Tpd_clk_out;
  156       mem_enable <= '0' after Tpd_clk_out;
  157     end write;
  158 
  159 
  160     procedure bus_read (address : in dlx_address;
  161                     data_width : in mem_width;
  162                     instr_fetch : in boolean;
  163                     data : out dlx_word;
  164                     signal phi1, phi2 : in bit;    -- 2-phase non-overlapping clks
  165                     signal reset : in bit;         -- synchronous reset input
  166                     signal a : out dlx_address;    -- address bus output
  167                     signal d : inout dlx_word_bus; -- bidirectional data bus
  168                     signal width : out mem_width;  -- byte/halfword/word
  169                     signal write_enable : out bit; -- selects read/write cycle
  170                     signal mem_enable : out bit;   -- starts memory cycle
  171                     signal ifetch : out bit;       -- indicates instruction eftch
  172                     signal ready : in bit;         -- status from memory system
  173                     Tpd_clk_out : in time          -- clock to output delay
  174                    ) is
  175 
  176     begin
  177       wait until phi1 = '1';
  178       if reset = '1' then
  179         return;
  180       end if;
  181       a <= address after Tpd_clk_out;
  182       width <= data_width after Tpd_clk_out;
  183       mem_enable <= '1' after Tpd_clk_out;
  184       ifetch <= bit'val(boolean'pos(instr_fetch)) after Tpd_clk_out;
  185       loop
  186         wait until phi2 = '0';
  187         exit when ready = '1' or reset = '1';
  188       end loop;
  189       data := d;
  190       mem_enable <= '0' after Tpd_clk_out;
  191     end bus_read;
  192 
  193 
  194   begin -- interpreter
  195     --
  196     -- reset the processor
  197     --
  198     d <= null;
  199     halt <= '0';
  200     write_enable <= '0';
  201     mem_enable <= '0';
  202     reg(0) := X"0000_0000";
  203     PC := X"0000_0000";
  204     user_mode := false;
  205     --
  206     -- fetch-decode-execute loop
  207     --
  208     loop
  209       --
  210       -- fetch next instruction
  211       --
  212       if debug then
  213         write(L, tag);
  214         write(L, string'(": fetching instruction..."));
  215         writeline(output, L);
  216       end if;
  217       --
  218       bus_read(PC, width_word, true, IR,
  219          phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
  220          Tpd_clk_out);
  221       exit when reset = '1';
  222       --
  223       -- increment the PC to point to the following instruction
  224       --
  225       if debug then
  226         write(L, tag);
  227         write(L, string'(": incrementing PC..."));
  228         writeline(output, L);
  229       end if;
  230       --
  231       bv_add(PC, PC_incr, PC, overflow);
  232       --
  233       -- decode the instruction
  234       --
  235       if debug then
  236         write(L, tag);
  237         write(L, string'(": decoding instruction..."));
  238         writeline(output, L);
  239       end if;
  240       --
  241       IR_opcode_num := bv_to_natural(IR_opcode);
  242       IR_sp_func_num := bv_to_natural(IR_sp_func);
  243       IR_fp_func_num := bv_to_natural(IR_fp_func);
  244       rs1 := bv_to_natural(IR_rs1);
  245       rs2 := bv_to_natural(IR_rs2);
  246       Itype_rd := bv_to_natural(IR_Itype_rd);
  247       Rtype_rd := bv_to_natural(IR_Rtype_rd);
  248       --
  249       -------------------------------------------------------------------------
  250       --  instrumentation: increment counter for decoded instruction
  251       -------------------------------------------------------------------------
  252       --
  253       op_count(IR_opcode_num) := op_count(IR_opcode_num) + 1;
  254       if IR_opcode = op_special then
  255         sp_func_count(IR_sp_func_num) := sp_func_count(IR_sp_func_num) + 1;
  256       elsif IR_opcode = op_fparith then
  257         fp_func_count(IR_fp_func_num) := fp_func_count(IR_fp_func_num) + 1;
  258       end if;
  259       instr_count := instr_count + 1;
  260       --  
  261       -------------------------------------------------------------------------
  262       --
  263       -- exectute
  264       --
  265       if debug then
  266         write(L, tag);
  267         write(L, string'(": executing instruction..."));
  268         writeline(output, L);
  269       end if;
  270       --
  271       case IR_opcode is
  272         when op_special =>
  273           case IR_sp_func is
  274             WHEN sp_func_nop =>
  275               null;
  276             when sp_func_sll =>
  277               reg(Rtype_rd) := bv_sll(reg(rs1), bv_to_natural(reg(rs2)(27 to 31)));
  278             when sp_func_srl =>
  279               reg(Rtype_rd) := bv_srl(reg(rs1), bv_to_natural(reg(rs2)(27 to 31)));
  280             when sp_func_sra =>
  281               reg(Rtype_rd) := bv_sra(reg(rs1), bv_to_natural(reg(rs2)(27 to 31)));
  282             when sp_func_sequ =>
  283               if reg(rs1) = reg(rs2) then
  284                 reg(Rtype_rd) := X"0000_0001";
  285               else
  286                 reg(Rtype_rd) := X"0000_0000";
  287               end if;
  288             when sp_func_sneu =>
  289               if reg(rs1) /= reg(rs2) then
  290                 reg(Rtype_rd) := X"0000_0001";
  291               else
  292                 reg(Rtype_rd) := X"0000_0000";
  293               end if;
  294             when sp_func_sltu =>
  295               if reg(rs1) < reg(rs2) then
  296                 reg(Rtype_rd) := X"0000_0001";
  297               else
  298                 reg(Rtype_rd) := X"0000_0000";
  299               end if;
  300             when sp_func_sgtu =>
  301               if reg(rs1) > reg(rs2) then
  302                 reg(Rtype_rd) := X"0000_0001";
  303               else
  304                 reg(Rtype_rd) := X"0000_0000";
  305               end if;
  306             when sp_func_sleu =>
  307               if reg(rs1) <= reg(rs2) then
  308                 reg(Rtype_rd) := X"0000_0001";
  309               else
  310                 reg(Rtype_rd) := X"0000_0000";
  311               end if;
  312             when sp_func_sgeu =>
  313               if reg(rs1) >= reg(rs2) then
  314                 reg(Rtype_rd) := X"0000_0001";
  315               else
  316                 reg(Rtype_rd) := X"0000_0000";
  317               end if;
  318             when sp_func_add =>
  319               bv_add(reg(rs1), reg(rs2), reg(Rtype_rd), overflow);
  320             when sp_func_addu =>
  321               bv_addu(reg(rs1), reg(rs2), reg(Rtype_rd), overflow);
  322             when sp_func_sub =>
  323               bv_sub(reg(rs1), reg(rs2), reg(Rtype_rd), overflow);
  324             when sp_func_subu =>
  325               bv_subu(reg(rs1), reg(rs2), reg(Rtype_rd), overflow);
  326             when sp_func_and =>
  327               reg(Rtype_rd) := reg(rs1) and reg(rs2);
  328             when sp_func_or =>
  329               reg(Rtype_rd) := reg(rs1) or reg(rs2);
  330             when sp_func_xor =>
  331               reg(Rtype_rd) := reg(rs1) xor reg(rs2);
  332             when sp_func_seq =>
  333               if reg(rs1) = reg(rs2) then
  334                 reg(Rtype_rd) := X"0000_0001";
  335               else
  336                 reg(Rtype_rd) := X"0000_0000";
  337               end if;
  338             when sp_func_sne =>
  339               if reg(rs1) /= reg(rs2) then
  340                 reg(Rtype_rd) := X"0000_0001";
  341               else
  342                 reg(Rtype_rd) := X"0000_0000";
  343               end if;
  344             when sp_func_slt =>
  345                if bv_lt(reg(rs1), reg(rs2)) then
  346                 reg(Rtype_rd) := X"0000_0001";
  347               else
  348                 reg(Rtype_rd) := X"0000_0000";
  349               end if;
  350             when sp_func_sgt =>
  351               if bv_gt(reg(rs1), reg(rs2)) then
  352                 reg(Rtype_rd) := X"0000_0001";
  353               else
  354                 reg(Rtype_rd) := X"0000_0000";
  355               end if;
  356             when sp_func_sle =>
  357               if bv_le(reg(rs1), reg(rs2)) then
  358                 reg(Rtype_rd) := X"0000_0001";
  359               else
  360                 reg(Rtype_rd) := X"0000_0000";
  361               end if;
  362             when sp_func_sge =>
  363               if bv_ge(reg(rs1), reg(rs2)) then
  364                 reg(Rtype_rd) := X"0000_0001";
  365               else
  366                 reg(Rtype_rd) := X"0000_0000";
  367               end if;
  368             when sp_func_movi2s =>
  369               assert false
  370                 report "MOVI2S instruction not implemented" severity warning;
  371             when sp_func_movs2i =>
  372               assert false
  373                 report "MOVS2I instruction not implemented" severity warning;
  374             when sp_func_movf =>
  375               assert false
  376                 report "MOVF instruction not implemented" severity warning;
  377             when sp_func_movd =>
  378               assert false
  379                 report "MOVD instruction not implemented" severity warning;
  380             when sp_func_movfp2i =>
  381               reg(Rtype_rd) := fp_reg(rs1);
  382             when sp_func_movi2fp =>
  383               fp_reg(Rtype_rd) := reg(rs1);
  384             when others =>
  385               assert false
  386                 report "undefined special instruction function" severity error;
  387           end case;
  388         when op_fparith =>
  389           case IR_fp_func is
  390             when fp_func_mult =>
  391               bv_mult(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), overflow);
  392             when fp_func_multu =>
  393               bv_multu(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), overflow);
  394             when fp_func_div =>
  395               bv_div(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), div_by_zero, overflow);
  396             when fp_func_divu =>
  397               bv_divu(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), div_by_zero);
  398             when fp_func_addf | fp_func_subf | fp_func_multf | fp_func_divf |
  399               fp_func_addd | fp_func_subd | fp_func_multd | fp_func_divd |
  400               fp_func_cvtf2d | fp_func_cvtf2i | fp_func_cvtd2f |
  401               fp_func_cvtd2i | fp_func_cvti2f | fp_func_cvti2d |
  402               fp_func_eqf | fp_func_nef | fp_func_ltf | fp_func_gtf |
  403               fp_func_lef | fp_func_gef | fp_func_eqd | fp_func_ned |
  404               fp_func_ltd | fp_func_gtd | fp_func_led | fp_func_ged =>
  405               assert false
  406                 report "floating point instructions not implemented" severity warning;
  407             when others =>
  408               assert false
  409                 report "undefined floating point instruction function" severity error;
  410           end case;
  411         when op_j  =>
  412           bv_add(PC, bv_sext(IR_immed26, 32), PC, overflow);
  413         when op_jal =>
  414           reg(link_reg) := PC;
  415           bv_add(PC, bv_sext(IR_immed26, 32), PC, overflow);
  416         when op_beqz =>
  417           if reg(rs1) = X"0000_0000" then
  418             bv_add(PC, bv_sext(IR_immed16, 32), PC, overflow);
  419           end if;
  420         when op_bnez =>
  421           if reg(rs1) /= X"0000_0000" then
  422             bv_add(PC, bv_sext(IR_immed16, 32), PC, overflow);
  423           end if;
  424         when op_bfpt =>
  425           assert false
  426             report "BFPT instruction not implemented" severity warning;
  427         when op_bfpf =>
  428           assert false
  429             report "BFPF instruction not implemented" severity warning;
  430         when op_addi =>
  431           bv_add(reg(rs1), bv_sext(IR_immed16, 32), reg(Itype_rd), overflow);
  432         when op_addui =>
  433           bv_addu(reg(rs1), bv_zext(IR_immed16, 32), reg(Itype_rd), overflow);
  434         when op_subi =>
  435           bv_sub(reg(rs1), bv_sext(IR_immed16, 32), reg(Itype_rd), overflow);
  436         when op_subui =>
  437           bv_subu(reg(rs1), bv_zext(IR_immed16, 32), reg(Itype_rd), overflow);
  438         when op_slli =>
  439           reg(Itype_rd) := bv_sll(reg(rs1), bv_to_natural(IR_immed16(11 to 15)));
  440         when op_srli =>
  441           reg(Itype_rd) := bv_srl(reg(rs1), bv_to_natural(IR_immed16(11 to 15)));
  442         when op_srai =>
  443           reg(Itype_rd) := bv_sra(reg(rs1), bv_to_natural(IR_immed16(11 to 15)));
  444         when op_andi =>
  445           reg(Itype_rd) := reg(rs1) and bv_zext(IR_immed16, 32);
  446         when op_ori =>
  447           reg(Itype_rd) := reg(rs1) or bv_zext(IR_immed16, 32);
  448         when op_xori =>
  449           reg(Itype_rd) := reg(rs1) xor bv_zext(IR_immed16, 32);
  450         when op_lhi =>
  451           reg(Itype_rd) := IR_immed16 & X"0000";
  452         when op_rfe =>
  453           assert false
  454             report "RFE instruction not implemented" severity warning;
  455         when op_trap =>
  456           assert false
  457             report "TRAP instruction encountered, execution halted"
  458             severity note;
  459           halt <= '1' after Tpd_clk_out;
  460           ---------------------------------------------------------------------
  461           --  instrumentation: dump counters
  462           ---------------------------------------------------------------------
  463           instrumentation_dump;
  464           ---------------------------------------------------------------------
  465           wait until reset = '1';
  466           exit;
  467         when op_jr =>
  468           PC := reg(rs1);
  469         when op_jalr =>
  470           reg(link_reg) := PC;
  471           PC := reg(rs1);
  472         when op_seqi =>
  473           if reg(rs1) = bv_sext(IR_immed16, 32) then
  474             reg(Itype_rd) := X"0000_0001";
  475           else
  476             reg(Itype_rd) := X"0000_0000";
  477           end if;
  478         when op_snei =>
  479           if reg(rs1) /= bv_sext(IR_immed16, 32) then
  480             reg(Itype_rd) := X"0000_0001";
  481           else
  482             reg(Itype_rd) := X"0000_0000";
  483           end if;
  484         when op_slti =>
  485           if bv_lt(reg(rs1), bv_sext(IR_immed16, 32)) then
  486             reg(Itype_rd) := X"0000_0001";
  487           else
  488             reg(Itype_rd) := X"0000_0000";
  489           end if;
  490         when op_sgti =>
  491           if bv_gt(reg(rs1), bv_sext(IR_immed16, 32)) then
  492             reg(Itype_rd) := X"0000_0001";
  493           else
  494             reg(Itype_rd) := X"0000_0000";
  495           end if;
  496         when op_slei =>
  497           if bv_le(reg(rs1), bv_sext(IR_immed16, 32)) then
  498             reg(Itype_rd) := X"0000_0001";
  499           else
  500             reg(Itype_rd) := X"0000_0000";
  501           end if;
  502         when op_sgei =>
  503           if bv_ge(reg(rs1), bv_sext(IR_immed16, 32)) then
  504             reg(Itype_rd) := X"0000_0001";
  505           else
  506             reg(Itype_rd) := X"0000_0000";
  507           end if;
  508         when op_lb =>
  509           bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
  510           bus_read(mem_addr, width_byte, false, mem_data,
  511             phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
  512             Tpd_clk_out);
  513           exit when reset = '1';
  514           case ls_2_addr_bits'(mem_addr(1 downto 0)) is
  515             when B"00" =>
  516               reg(Itype_rd) := bv_sext(mem_data(0 to 7), 32);
  517             when B"01" =>
  518               reg(Itype_rd) := bv_sext(mem_data(8 to 15), 32);
  519             when B"10" =>
  520               reg(Itype_rd) := bv_sext(mem_data(16 to 23), 32);
  521             when B"11" =>
  522               reg(Itype_rd) := bv_sext(mem_data(24 to 31), 32);
  523           end case;
  524         when op_lh =>
  525           bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
  526           bus_read(mem_addr, width_halfword, false, mem_data,
  527             phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
  528             Tpd_clk_out);
  529           exit when reset = '1';
  530           if mem_addr(1) = '0' then
  531             reg(Itype_rd) := bv_sext(mem_data(0 to 15), 32);
  532           else
  533             reg(Itype_rd) := bv_sext(mem_data(16 to 31), 32);
  534           end if;
  535         when op_lw =>
  536           bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
  537           bus_read(mem_addr, width_word, false, mem_data,
  538             phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
  539             Tpd_clk_out);
  540           exit when reset = '1';
  541           reg(Itype_rd) := mem_data;
  542         when op_lbu =>
  543           bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
  544           bus_read(mem_addr, width_byte, false, mem_data,
  545             phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
  546             Tpd_clk_out);
  547           exit when reset = '1';
  548           case ls_2_addr_bits'(mem_addr(1 downto 0)) is
  549             when B"00" =>
  550               reg(Itype_rd) := bv_zext(mem_data(0 to 7), 32);
  551             when B"01" =>
  552               reg(Itype_rd) := bv_zext(mem_data(8 to 15), 32);
  553             when B"10" =>
  554               reg(Itype_rd) := bv_zext(mem_data(16 to 23), 32);
  555             when B"11" =>
  556               reg(Itype_rd) := bv_zext(mem_data(24 to 31), 32);
  557           end case;
  558         when op_lhu =>
  559           bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
  560           bus_read(mem_addr, width_halfword, false, mem_data,
  561             phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
  562             Tpd_clk_out);
  563           exit when reset = '1';
  564           if mem_addr(1) = '0' then
  565             reg(Itype_rd) := bv_zext(mem_data(0 to 15), 32);
  566           else
  567             reg(Itype_rd) := bv_zext(mem_data(16 to 31), 32);
  568           end if;
  569         when op_lf =>
  570           assert false
  571             report "LF instruction not implemented" severity warning;
  572         when op_ld =>
  573           assert false
  574             report "LD instruction not implemented" severity warning;
  575         when op_sb =>
  576           bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
  577           mem_data := X"0000_0000";
  578           case ls_2_addr_bits'(mem_addr(1 downto 0)) is
  579             when B"00" =>
  580               mem_data(0 to 7) := reg(Itype_rd)(0 to 7);
  581             when B"01" =>
  582               mem_data(8 to 15) := reg(Itype_rd)(0 to 7);
  583             when B"10" =>
  584               mem_data(16 to 23) := reg(Itype_rd)(0 to 7);
  585             when B"11" =>
  586               mem_data(24 to 31) := reg(Itype_rd)(0 to 7);
  587           end case;
  588           write(mem_addr, width_halfword, mem_data,
  589             phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
  590             Tpd_clk_out);
  591           exit when reset = '1';
  592         when op_sh =>
  593           bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
  594           mem_data := X"0000_0000";
  595           if mem_addr(1) = '0' then
  596             mem_data(0 to 15) := reg(Itype_rd)(0 to 15);
  597           else
  598             mem_data(16 to 31) := reg(Itype_rd)(0 to 15);
  599           end if;
  600           write(mem_addr, width_halfword, mem_data,
  601             phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
  602             Tpd_clk_out);
  603           exit when reset = '1';
  604         when op_sw =>
  605           bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
  606           mem_data := reg(Itype_rd);
  607           write(mem_addr, width_word, mem_data,
  608             phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
  609             Tpd_clk_out);
  610           exit when reset = '1';
  611         when op_sf =>
  612           assert false
  613             report "SF instruction not implemented" severity warning;
  614         when op_sd =>
  615           assert false
  616             report "SD instruction not implemented" severity warning;
  617         when op_sequi =>
  618           if reg(rs1) = bv_zext(IR_immed16, 32) then
  619             reg(Itype_rd) := X"0000_0001";
  620           else
  621             reg(Itype_rd) := X"0000_0000";
  622           end if;
  623         when op_sneui =>
  624           if reg(rs1) /= bv_zext(IR_immed16, 32) then
  625             reg(Itype_rd) := X"0000_0001";
  626           else
  627             reg(Itype_rd) := X"0000_0000";
  628           end if;
  629         when op_sltui =>
  630           if reg(rs1) < bv_zext(IR_immed16, 32) then
  631             reg(Itype_rd) := X"0000_0001";
  632           else
  633             reg(Itype_rd) := X"0000_0000";
  634           end if;
  635         when op_sgtui =>
  636           if reg(rs1) > bv_zext(IR_immed16, 32) then
  637             reg(Itype_rd) := X"0000_0001";
  638           else
  639             reg(Itype_rd) := X"0000_0000";
  640           end if;
  641         when op_sleui =>
  642           if reg(rs1) <= bv_zext(IR_immed16, 32) then
  643             reg(Itype_rd) := X"0000_0001";
  644           else
  645             reg(Itype_rd) := X"0000_0000";
  646           end if;
  647         when op_sgeui =>
  648           if reg(rs1) >= bv_zext(IR_immed16, 32) then
  649             reg(Itype_rd) := X"0000_0001";
  650           else
  651             reg(Itype_rd) := X"0000_0000";
  652           end if;
  653         when others =>
  654           assert false
  655             report "undefined instruction" severity error;
  656       end case;
  657       --
  658       -- fix up R0 in case it was overwritten
  659       --
  660       reg(0) := X"0000_0000";
  661       --
  662       if debug then
  663         write(L, tag);
  664         write(L, string'(": end of execution"));
  665         writeline(output, L);
  666       end if;
  667       if instr_count mod 100 = 0 then
  668         write(L, tag);
  669         write(L, string'(": executed "));
  670         write(L, instr_count);
  671         write(L, string'(" instructions"));
  672         writeline(output, L);
  673       end if;
  674       --
  675     end loop;
  676     --
  677     -- loop is only exited when reset active: wait until it goes inactive
  678     --
  679     assert reset = '1'
  680       report "reset code reached with reset = '0'" severity error;
  681     wait until phi2 = '0' and reset = '0';
  682     --
  683     -- process interpreter now starts again from beginning
  684     --
  685   end process interpreter;
  686 
  687 end instrumented;
  688 

This page was generated using GHDL 0.14 (20040829) [Sokcho edition], a program written by Tristan Gingold