dlx/memory_test-bench.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: memory_test-bench.vhdl,v $  $Revision: 1.1 $  $Date: 2000/05/08 14:36:48 $
   25 --
   26 --------------------------------------------------------------------------
   27 --
   28 --  Architecture for test bench for behavioural architecture of memory
   29 --
   30 
   31 
   32 use std.textio.all,
   33     work.dlx_types.all,
   34     work.mem_types.all,
   35     work.bv_arithmetic.bv_addu,
   36     work.images.image_hex;
   37 
   38 architecture bench of memory_test is
   39 
   40   component clock_gen
   41     port (phi1, phi2 : out bit;
   42           reset : out bit);
   43   end component;
   44 
   45   component memory
   46     port (phi1, phi2 : in bit;
   47           a : in dlx_address;
   48           d : inout dlx_word_bus bus;
   49           width : in mem_width;
   50           write_enable : in bit;
   51           burst : in bit;
   52           mem_enable : in bit;
   53           ready : out bit);
   54   end component;
   55 
   56   for cg : clock_gen
   57     use entity work.clock_gen(behaviour)
   58       generic map (Tpw => 8 ns, Tps => 2 ns);
   59 
   60   for mem : memory
   61     use entity work.memory(behaviour)
   62       generic map (mem_size => 65536,
   63                    Tac1 => 95 ns, Tacb => 15 ns, Tpd_clk_out => 2 ns);
   64 
   65   signal phi1, phi2, reset : bit;
   66   signal a : dlx_address;
   67   signal d : dlx_word_bus bus;
   68   signal width : mem_width;
   69   signal write_enable, mem_enable, burst, ifetch, ready : bit;
   70 
   71 
   72 begin
   73 
   74   cg : clock_gen
   75     port map (phi1, phi2, reset);
   76 
   77   mem : memory
   78     port map (phi1, phi2, a, d, width, write_enable, burst, mem_enable, ready);
   79 
   80   test: process
   81 
   82     variable data_word : dlx_word;
   83     variable L : line;
   84     VARIABLE blk : dlx_word_array(1 to 4);
   85 
   86     procedure write (address : in dlx_address;
   87                    data_width : in mem_width;
   88                    data : in dlx_word;
   89                    Tpd_clk_out : in time          -- clock to output delay
   90                   ) is
   91 
   92     begin -- write
   93       wait until phi1 = '1';
   94       if reset = '1' then
   95         return;
   96       end if;
   97       a <= address after Tpd_clk_out;
   98       width <= data_width after Tpd_clk_out;
   99       d <= data after Tpd_clk_out;
  100       write_enable <= '1' after Tpd_clk_out;
  101       burst <= '0' after Tpd_Clk_Out;
  102       mem_enable <= '1' after Tpd_clk_out;
  103       ifetch <= '0' after Tpd_clk_out;
  104       loop
  105         wait until phi2 = '0';
  106         exit when ready = '1' or reset = '1';
  107       end loop;
  108       d <= null after Tpd_clk_out;
  109       write_enable <= '0' after Tpd_clk_out;
  110       mem_enable <= '0' after Tpd_clk_out;
  111     end write;
  112 
  113 
  114     procedure read (address : in dlx_address;
  115                   data_width : in mem_width;
  116                   instr_fetch : in boolean;
  117                   data : out dlx_word;
  118                   Tpd_clk_out : in time          -- clock to output delay
  119                  ) is
  120 
  121     begin -- read
  122       wait until phi1 = '1';
  123       if reset = '1' then
  124         return;
  125       end if;
  126       a <= address after Tpd_clk_out;
  127       width <= data_width after Tpd_clk_out;
  128       write_enable <= '0' after Tpd_clk_out;
  129       burst <= '0' after Tpd_Clk_Out;
  130       mem_enable <= '1' after Tpd_clk_out;
  131       ifetch <= bit'val(boolean'pos(instr_fetch)) after Tpd_clk_out;
  132       loop
  133         wait until phi2 = '0';
  134         exit when ready = '1' or reset = '1';
  135       end loop;
  136       data := d;
  137       mem_enable <= '0' after Tpd_clk_out;
  138     end read;
  139 
  140 
  141     procedure write_burst (address : in dlx_address;
  142                    data : in dlx_word_array;
  143                    Tpd_clk_out : in time          -- clock to output delay
  144                   ) is
  145       VARIABLE next_address : dlx_address := address;
  146       VARIABLE ignore_overflow : boolean;
  147       VARIABLE index : natural;
  148     begin -- write_burst
  149       wait until phi1 = '1';
  150       if reset = '1' then
  151         return;
  152       end if;
  153       width <= width_word after Tpd_clk_out;
  154       write_enable <= '1' after Tpd_clk_out;
  155       mem_enable <= '1' after Tpd_clk_out;
  156       ifetch <= '0' after Tpd_clk_out;
  157       burst <= '1' after Tpd_Clk_Out;
  158       index := data'left;
  159       burst_loop : LOOP
  160         IF (index = data'right) THEN
  161           burst <= '0' after Tpd_Clk_Out;
  162         END IF;
  163         a <= next_address after Tpd_clk_out;
  164         d <= data(index) after Tpd_clk_out;
  165         wait_loop : LOOP
  166           WAIT UNTIL phi2 = '0';
  167           EXIT burst_loop WHEN reset = '1' OR (ready = '1' AND index = data'right);
  168           EXIT wait_loop WHEN ready = '1';
  169         END LOOP wait_loop;
  170         index := index + 1;
  171         bv_addu(next_address, X"00000004", next_address, ignore_overflow);
  172       END LOOP burst_loop;
  173       d <= null after Tpd_clk_out;
  174       write_enable <= '0' after Tpd_clk_out;
  175       mem_enable <= '0' after Tpd_clk_out;
  176     end write_burst;
  177 
  178 
  179     procedure read_burst (address : in dlx_address;
  180                   data : out dlx_word_array;
  181                   Tpd_clk_out : in time          -- clock to output delay
  182                  ) is
  183       VARIABLE next_address : dlx_address := address;
  184       VARIABLE ignore_overflow : boolean;
  185       VARIABLE index : natural;
  186     begin -- read_burst
  187       wait until phi1 = '1';
  188       if reset = '1' then
  189         return;
  190       end if;
  191       width <= width_word after Tpd_clk_out;
  192       write_enable <= '0' after Tpd_clk_out;
  193       mem_enable <= '1' after Tpd_clk_out;
  194       ifetch <= '0' after Tpd_clk_out;
  195       burst <= '1' after Tpd_Clk_Out;
  196       index := data'left;
  197       burst_loop : LOOP
  198         IF (index = data'right) THEN
  199           burst <= '0' after Tpd_Clk_Out;
  200         END IF;
  201         a <= next_address after Tpd_clk_out;
  202         wait_loop : LOOP
  203           WAIT UNTIL phi2 = '0';
  204           data(index) := d;
  205           EXIT burst_loop WHEN reset = '1' OR (ready = '1' AND index = data'right);
  206           EXIT wait_loop WHEN ready = '1';
  207         END LOOP wait_loop;
  208         index := index + 1;
  209         bv_addu(next_address, X"00000004", next_address, ignore_overflow);
  210       END LOOP burst_loop;
  211       mem_enable <= '0' after Tpd_clk_out;
  212     end read_burst;
  213 
  214 
  215   begin
  216     --  Just to create drivers.
  217     a <= (others => '0');
  218     width <= width_byte;
  219     d <= (others => '0');
  220     write_enable <= '0';
  221     burst <= '0';
  222     mem_enable <= '0';
  223     ifetch <= '0';
  224     wait until reset = '0';
  225 
  226     write(L, string'("Write word X""00000004"" to 4:"));
  227     writeline(output, L);
  228     write(X"0000_0004", width_word, X"00000004", 2 ns);
  229     --
  230     write(L, string'("Read word from X""00000004"":"));
  231     writeline(output, L);
  232     data_word := X"0000_0000";
  233     read(X"0000_0004", width_word, false, data_word, 2 ns);
  234     write(L, string'("  result:"));
  235     write(L, image_hex(data_word));
  236     writeline(output, L);
  237     --
  238     write(L, string'("Write halfword X""2222"" to 0:"));
  239     writeline(output, L);
  240     write(X"0000_0000", width_halfword, X"2222_0000", 2 ns);
  241     --
  242     write(L, string'("Write halfword X""3333"" to 2:"));
  243     writeline(output, L);
  244     write(X"0000_0002", width_halfword, X"0000_3333", 2 ns);
  245     --
  246     write(L, string'("Read word from X""00000000"":"));
  247     writeline(output, L);
  248     data_word := X"0000_0000";
  249     read(X"0000_0000", width_word, false, data_word, 2 ns);
  250     write(L, string'("  result:"));
  251     write(L, image_hex(data_word));
  252     writeline(output, L);
  253     --
  254     write(L, string'("Read halfword from X""00000003"":"));
  255     writeline(output, L);
  256     data_word := X"0000_0000";
  257     read(X"0000_0003", width_halfword, false, data_word, 2 ns);
  258     write(L, string'("  result:"));
  259     write(L, image_hex(data_word));
  260     writeline(output, L);
  261     --
  262     write(L, string'("Write bytes X""44"" to 4, X""55"" to 5, X""66"" to 6, X""77"" to 7:"));
  263     writeline(output, L);
  264     write(X"0000_0004", width_byte, X"44_00_00_00", 2 ns);
  265     write(X"0000_0005", width_byte, X"00_55_00_00", 2 ns);
  266     write(X"0000_0006", width_byte, X"00_00_66_00", 2 ns);
  267     write(X"0000_0007", width_byte, X"00_00_00_77", 2 ns);
  268     --
  269     write(L, string'("Read word from X""00000004"":"));
  270     writeline(output, L);
  271     data_word := X"0000_0000";
  272     read(X"0000_0004", width_word, false, data_word, 2 ns);
  273     write(L, string'("  result:"));
  274     write(L, image_hex(data_word));
  275     writeline(output, L);
  276     --
  277     write(L, string'("Read byte from X""00000004"":"));
  278     writeline(output, L);
  279     data_word := X"0000_0000";
  280     read(X"0000_0004", width_byte, false, data_word, 2 ns);
  281     write(L, string'("  result:"));
  282     write(L, image_hex(data_word));
  283     writeline(output, L);
  284     --
  285     write(L, string'("Read byte from X""00000005"":"));
  286     writeline(output, L);
  287     data_word := X"0000_0000";
  288     read(X"0000_0005", width_byte, false, data_word, 2 ns);
  289     write(L, string'("  result:"));
  290     write(L, image_hex(data_word));
  291     writeline(output, L);
  292     --
  293     write(L, string'("Read byte from X""00000006"":"));
  294     writeline(output, L);
  295     data_word := X"0000_0000";
  296     read(X"0000_0006", width_byte, false, data_word, 2 ns);
  297     write(L, string'("  result:"));
  298     write(L, image_hex(data_word));
  299     writeline(output, L);
  300     --
  301     write(L, string'("Read byte from X""00000007"":"));
  302     writeline(output, L);
  303     data_word := X"0000_0000";
  304     read(X"0000_0007", width_byte, false, data_word, 2 ns);
  305     write(L, string'("  result:"));
  306     write(L, image_hex(data_word));
  307     writeline(output, L);
  308     --
  309     write(L, string'("Write burst to 8..11:"));
  310     writeline(output, L);
  311     blk := (X"88888888", X"99999999", X"AAAAAAAA", X"BBBBBBBB");
  312     write_burst(X"0000_0008", blk, 2 ns);
  313     --
  314     write(L, string'("Read burst from 8..11:"));
  315     writeline(output, L);
  316     blk := (OTHERS => X"0000_0000");
  317     read_burst(X"0000_0008", blk, 2 ns);
  318     write(L, string'("  result: ("));
  319     FOR i IN blk'range LOOP
  320       write(L, image_hex(blk(i)));
  321       IF (i /= blk'right) THEN
  322         write(L, string'(", "));
  323       END IF;
  324     END LOOP;                            --  i
  325     write(L, ')');
  326     writeline(output, L);
  327     --
  328     -- This should hang
  329     write(L, string'("Read word from X""00100000"":"));
  330     writeline(output, L);
  331     data_word := X"0000_0000";
  332     read(X"0010_0000", width_word, false, data_word, 2 ns);
  333     write(L, string'("  result:"));
  334     write(L, data_word);
  335     writeline(output, L);
  336     --
  337   end process test;
  338 
  339 end bench;
  340 

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