- added
git-svn-id: http://moon:8086/svn/vhdl/trunk@1424 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
std_opt="--workdir=work"
|
||||
srcdir="./src"
|
||||
|
||||
ghdl --remove $std_opt
|
||||
ghdl -i $std_opt $srcdir/*.vhdl
|
||||
ghdl -m $std_opt dlx_test_behaviour
|
||||
ghdl -r dlx_test_behaviour --vcd=dlx_test_behaviour.vcd --assert-level=note
|
||||
@@ -0,0 +1,48 @@
|
||||
This directory contains the source files for the DLX model suite.
|
||||
|
||||
The following copyright holds:
|
||||
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
This suite is distributed as is, with no documentation or support. If
|
||||
I get time, I may provide documentation at a later date.
|
||||
|
||||
Included in the directory is a file called module-directory, that
|
||||
lists the source files with a brief description of each. You should
|
||||
be able to compile them in the order listed.
|
||||
|
||||
To run a simulation that includes the memory entity, you will need to
|
||||
have a file called dlx.out in the current working directory. This is
|
||||
the memory image file loaded by the memory entity, containing DLX
|
||||
instructions and data. The distribution directory contains two sample
|
||||
DLX programs, simple.s and test_loop.s, along with assembled versions
|
||||
in simple.out and test_loop.out. You can copy one of the .out files
|
||||
to dlx.out to run the simulation.
|
||||
|
||||
I would be pleased to hear comments or bug reports (ie, bugs in the
|
||||
model, not bugs in your VHDL tools!). You can mail them to me at the
|
||||
above e-mail address.
|
||||
|
||||
Have fun!
|
||||
|
||||
Peter A.
|
||||
|
||||
2 November 1993.
|
||||
@@ -0,0 +1,38 @@
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Software Liability Information
|
||||
|
||||
The software package(s) (VHDL models, style guides, etc.) that you have are from
|
||||
the RASSP server (http://rassp.scra.org). SCRA is maintaining this server for
|
||||
DARPA as the RASSP Educator and Facilitator in order to provide current and
|
||||
easily accessible information to the research community. While SCRA & DARPA
|
||||
intend to keep the information accurate and timely, it cannot guarantee either.
|
||||
Errors may be brought to our attention via email at info@rassp.scra.org and will
|
||||
be corrected as soon as possible.
|
||||
|
||||
The use or purpose for which these Software Package(s) were developed may not be
|
||||
appropriate for your intended use. The authors or distributors of this code are
|
||||
not responsible for correctness or accuracy of the material in this package.
|
||||
This code may not be distributed for commercial purposes unless provided for in
|
||||
the software package itself.
|
||||
|
||||
|
||||
WARRANTY
|
||||
|
||||
BY USING THESE SOFTWARE PACKAGES, USER EXPRESSLY AGREES THAT USE IS AT USER'S
|
||||
SOLE RISK. IN NO EVENT SHALL THE UNITED STATES GOVERNMENT, SOUTH CAROLINA
|
||||
RESEARCH AUTHORITY (SCRA), THE AUTHORS, OR THE COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY INCIDENTAL, INDIRECT , SPECIAL, OR CONSEQUENTIAL DAMAGES WHATSOEVER ARISING
|
||||
OUT OF OR RELATING TO THE USE OF THE INFORMATION/SOFTWARE PROVIDED IN THIS
|
||||
PACKAGE. THE USER ASSUMES ALL RISKS, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PACKAGE
|
||||
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
|
||||
LOSSES SUSTAINED BY USER OR THIRD PARTIES OR A FAILURE OF THE PACKAGE TO
|
||||
OPERATE WITH ANY OTHER PACKAGES), EVEN IF THE UNITED STATES GOVERNMENT, SOUTH
|
||||
CAROLINA RESEARCH AUTHORITY (SCRA), THE AUTHORS, THE COPYRIGHT HOLDERS, OR OTHER
|
||||
PARTIES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE PACKAGE IS
|
||||
PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. NO
|
||||
WARRANTY OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE IS GIVEN OR
|
||||
IMPLIED. THE ENTIRE RISK AS TO THE QUALITY, VALIDITY, AND PERFORMANCE OF THE
|
||||
PACKAGE IS WITH THE USER. SHOULD THE PACKAGE PROVE DEFECTIVE, THE USER ASSUMES
|
||||
ANY COST OF NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,38 @@
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Software Liability Information
|
||||
|
||||
The software package(s) (VHDL models, style guides, etc.) that you have are from
|
||||
the RASSP server (http://rassp.scra.org). SCRA is maintaining this server for
|
||||
DARPA as the RASSP Educator and Facilitator in order to provide current and
|
||||
easily accessible information to the research community. While SCRA & DARPA
|
||||
intend to keep the information accurate and timely, it cannot guarantee either.
|
||||
Errors may be brought to our attention via email at info@rassp.scra.org and will
|
||||
be corrected as soon as possible.
|
||||
|
||||
The use or purpose for which these Software Package(s) were developed may not be
|
||||
appropriate for your intended use. The authors or distributors of this code are
|
||||
not responsible for correctness or accuracy of the material in this package.
|
||||
This code may not be distributed for commercial purposes unless provided for in
|
||||
the software package itself.
|
||||
|
||||
|
||||
WARRANTY
|
||||
|
||||
BY USING THESE SOFTWARE PACKAGES, USER EXPRESSLY AGREES THAT USE IS AT USER'S
|
||||
SOLE RISK. IN NO EVENT SHALL THE UNITED STATES GOVERNMENT, SOUTH CAROLINA
|
||||
RESEARCH AUTHORITY (SCRA), THE AUTHORS, OR THE COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY INCIDENTAL, INDIRECT , SPECIAL, OR CONSEQUENTIAL DAMAGES WHATSOEVER ARISING
|
||||
OUT OF OR RELATING TO THE USE OF THE INFORMATION/SOFTWARE PROVIDED IN THIS
|
||||
PACKAGE. THE USER ASSUMES ALL RISKS, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PACKAGE
|
||||
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
|
||||
LOSSES SUSTAINED BY USER OR THIRD PARTIES OR A FAILURE OF THE PACKAGE TO
|
||||
OPERATE WITH ANY OTHER PACKAGES), EVEN IF THE UNITED STATES GOVERNMENT, SOUTH
|
||||
CAROLINA RESEARCH AUTHORITY (SCRA), THE AUTHORS, THE COPYRIGHT HOLDERS, OR OTHER
|
||||
PARTIES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE PACKAGE IS
|
||||
PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. NO
|
||||
WARRANTY OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE IS GIVEN OR
|
||||
IMPLIED. THE ENTIRE RISK AS TO THE QUALITY, VALIDITY, AND PERFORMANCE OF THE
|
||||
PACKAGE IS WITH THE USER. SHOULD THE PACKAGE PROVE DEFECTIVE, THE USER ASSUMES
|
||||
ANY COST OF NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,81 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: alu-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 18:52:07 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture of ALU.
|
||||
--
|
||||
|
||||
|
||||
architecture behaviour of alu is
|
||||
|
||||
begin
|
||||
|
||||
alu_op: process (s1, s2, latch_en, func)
|
||||
|
||||
use work.bv_arithmetic.all;
|
||||
|
||||
variable stored_s1, stored_s2 : dlx_word;
|
||||
variable temp_result : dlx_word;
|
||||
variable temp_overflow : boolean;
|
||||
|
||||
begin
|
||||
if latch_en = '1' then
|
||||
stored_s1 := s1;
|
||||
stored_s2 := s2;
|
||||
end if;
|
||||
case func is
|
||||
when alu_pass_s1 =>
|
||||
temp_result := stored_s1;
|
||||
when alu_pass_s2 =>
|
||||
temp_result := stored_s2;
|
||||
when alu_and =>
|
||||
temp_result := stored_s1 and stored_s2;
|
||||
when alu_or =>
|
||||
temp_result := stored_s1 or stored_s2;
|
||||
when alu_xor =>
|
||||
temp_result := stored_s1 xor stored_s2;
|
||||
when alu_sll =>
|
||||
temp_result := bv_sll(stored_s1, bv_to_natural(stored_s2(27 to 31)));
|
||||
when alu_srl =>
|
||||
temp_result := bv_srl(stored_s1, bv_to_natural(stored_s2(27 to 31)));
|
||||
when alu_sra =>
|
||||
temp_result := bv_sra(stored_s1, bv_to_natural(stored_s2(27 to 31)));
|
||||
when alu_add =>
|
||||
bv_add(stored_s1, stored_s2, temp_result, temp_overflow);
|
||||
when alu_addu =>
|
||||
bv_addu(stored_s1, stored_s2, temp_result, temp_overflow);
|
||||
when alu_sub =>
|
||||
bv_sub(stored_s1, stored_s2, temp_result, temp_overflow);
|
||||
when alu_subu =>
|
||||
bv_subu(stored_s1, stored_s2, temp_result, temp_overflow);
|
||||
end case;
|
||||
result <= temp_result after Tpd;
|
||||
zero <= bit'val(boolean'pos(temp_result = dlx_word'(X"0000_0000"))) after Tpd;
|
||||
negative <= temp_result(0) after Tpd;
|
||||
overflow <= bit'val(boolean'pos(temp_overflow)) after Tpd;
|
||||
end process alu_op;
|
||||
|
||||
end behaviour;
|
||||
@@ -0,0 +1,45 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: alu.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 18:50:25 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for ALU.
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_types.all,
|
||||
work.alu_types.all;
|
||||
|
||||
entity alu is
|
||||
generic (Tpd : Time;
|
||||
tag : string := "";
|
||||
origin_x, origin_y : real := 0.0);
|
||||
port (s1 : in dlx_word;
|
||||
s2 : in dlx_word;
|
||||
result : out dlx_word;
|
||||
latch_en : in bit;
|
||||
func : in alu_func;
|
||||
zero, negative, overflow : out bit);
|
||||
end alu;
|
||||
@@ -0,0 +1,39 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: alu_types.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 18:48:41 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Package defining types for ALU.
|
||||
--
|
||||
|
||||
|
||||
package alu_types is
|
||||
|
||||
type alu_func is (alu_add, alu_addu, alu_sub, alu_subu,
|
||||
alu_and, alu_or, alu_xor,
|
||||
alu_sll, alu_srl, alu_sra,
|
||||
alu_pass_s1, alu_pass_s2);
|
||||
|
||||
end alu_types;
|
||||
@@ -0,0 +1,982 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: bv_arithmetic-body.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 22:50:39 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Bit vector arithmetic package body.
|
||||
--
|
||||
-- Does arithmetic and logical operations on bit vectors, treating them
|
||||
-- as either unsigned or signed (2's complement) integers. Leftmost bit
|
||||
-- is most significant or sign bit, rightmost bit is least significant
|
||||
-- bit. Dyadic operations need the two arguments to be of the same
|
||||
-- length, however their index ranges and directions may differ. Results
|
||||
-- must be of the same length as the operands.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
package body bv_arithmetic is
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Type conversions
|
||||
----------------------------------------------------------------
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_to_natural
|
||||
--
|
||||
-- Convert bit vector encoded unsigned integer to natural.
|
||||
----------------------------------------------------------------
|
||||
|
||||
function bv_to_natural(bv : in bit_vector) return natural is
|
||||
|
||||
variable result : natural := 0;
|
||||
|
||||
begin
|
||||
for index in bv'range loop
|
||||
result := result * 2 + bit'pos(bv(index));
|
||||
end loop;
|
||||
return result;
|
||||
end bv_to_natural;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- natural_to_bv
|
||||
--
|
||||
-- Convert natural to bit vector encoded unsigned integer.
|
||||
-- (length is used as the size of the result.)
|
||||
----------------------------------------------------------------
|
||||
|
||||
function natural_to_bv(nat : in natural;
|
||||
length : in natural) return bit_vector is
|
||||
|
||||
variable temp : natural := nat;
|
||||
variable result : bit_vector(0 to length-1);
|
||||
|
||||
begin
|
||||
for index in result'reverse_range loop
|
||||
result(index) := bit'val(temp rem 2);
|
||||
temp := temp / 2;
|
||||
end loop;
|
||||
return result;
|
||||
end natural_to_bv;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_to_integer
|
||||
--
|
||||
-- Convert bit vector encoded signed integer to integer
|
||||
----------------------------------------------------------------
|
||||
|
||||
function bv_to_integer(bv : in bit_vector) return integer is
|
||||
|
||||
variable temp : bit_vector(bv'range);
|
||||
variable result : integer := 0;
|
||||
|
||||
begin
|
||||
if bv(bv'left) = '1' then -- negative number
|
||||
temp := not bv;
|
||||
else
|
||||
temp := bv;
|
||||
end if;
|
||||
for index in bv'range loop -- sign bit of temp = '0'
|
||||
result := result * 2 + bit'pos(temp(index));
|
||||
end loop;
|
||||
if bv(bv'left) = '1' then
|
||||
result := (-result) - 1;
|
||||
end if;
|
||||
return result;
|
||||
end bv_to_integer;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- integer_to_bv
|
||||
--
|
||||
-- Convert integer to bit vector encoded signed integer.
|
||||
-- (length is used as the size of the result.)
|
||||
----------------------------------------------------------------
|
||||
|
||||
function integer_to_bv(int : in integer;
|
||||
length : in natural) return bit_vector is
|
||||
|
||||
variable temp : integer;
|
||||
variable result : bit_vector(0 to length-1);
|
||||
|
||||
begin
|
||||
if int < 0 then
|
||||
temp := -(int+1);
|
||||
else
|
||||
temp := int;
|
||||
end if;
|
||||
for index in result'reverse_range loop
|
||||
result(index) := bit'val(temp rem 2);
|
||||
temp := temp / 2;
|
||||
end loop;
|
||||
if int < 0 then
|
||||
result := not result;
|
||||
result(result'left) := '1';
|
||||
end if;
|
||||
return result;
|
||||
end integer_to_bv;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Arithmetic operations
|
||||
----------------------------------------------------------------
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_add
|
||||
--
|
||||
-- Signed addition with overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
procedure bv_add (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
overflow : out boolean) is
|
||||
|
||||
alias op1 : bit_vector(1 to bv1'length) is bv1;
|
||||
alias op2 : bit_vector(1 to bv2'length) is bv2;
|
||||
variable result : bit_vector(1 to bv_result'length);
|
||||
variable carry_in : bit;
|
||||
variable carry_out : bit := '0';
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length and bv1'length = bv_result'length
|
||||
report "bv_add: operands of different lengths"
|
||||
severity failure;
|
||||
for index in result'reverse_range loop
|
||||
carry_in := carry_out; -- of previous bit
|
||||
result(index) := op1(index) xor op2(index) xor carry_in;
|
||||
carry_out := (op1(index) and op2(index))
|
||||
or (carry_in and (op1(index) xor op2(index)));
|
||||
end loop;
|
||||
bv_result := result;
|
||||
overflow := carry_out /= carry_in;
|
||||
end bv_add;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- "+"
|
||||
--
|
||||
-- Signed addition without overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
function "+" (bv1, bv2 : in bit_vector) return bit_vector is
|
||||
|
||||
alias op1 : bit_vector(1 to bv1'length) is bv1;
|
||||
alias op2 : bit_vector(1 to bv2'length) is bv2;
|
||||
variable result : bit_vector(1 to bv1'length);
|
||||
variable carry_in : bit;
|
||||
variable carry_out : bit := '0';
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length
|
||||
-- use concatenation to work around Synthesia MINT code gen bug
|
||||
report '"' & '+' & '"' & ": operands of different lengths"
|
||||
severity failure;
|
||||
for index in result'reverse_range loop
|
||||
carry_in := carry_out; -- of previous bit
|
||||
result(index) := op1(index) xor op2(index) xor carry_in;
|
||||
carry_out := (op1(index) and op2(index))
|
||||
or (carry_in and (op1(index) xor op2(index)));
|
||||
end loop;
|
||||
return result;
|
||||
end "+";
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_sub
|
||||
--
|
||||
-- Signed subtraction with overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
procedure bv_sub (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
overflow : out boolean) is
|
||||
|
||||
-- subtraction implemented by adding ((not bv2) + 1), ie -bv2
|
||||
|
||||
alias op1 : bit_vector(1 to bv1'length) is bv1;
|
||||
alias op2 : bit_vector(1 to bv2'length) is bv2;
|
||||
variable result : bit_vector(1 to bv_result'length);
|
||||
variable carry_in : bit;
|
||||
variable carry_out : bit := '1';
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length and bv1'length = bv_result'length
|
||||
report "bv_sub: operands of different lengths"
|
||||
severity failure;
|
||||
for index in result'reverse_range loop
|
||||
carry_in := carry_out; -- of previous bit
|
||||
result(index) := op1(index) xor (not op2(index)) xor carry_in;
|
||||
carry_out := (op1(index) and (not op2(index)))
|
||||
or (carry_in and (op1(index) xor (not op2(index))));
|
||||
end loop;
|
||||
bv_result := result;
|
||||
overflow := carry_out /= carry_in;
|
||||
end bv_sub;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- "-"
|
||||
--
|
||||
-- Signed subtraction without overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
function "-" (bv1, bv2 : in bit_vector) return bit_vector is
|
||||
|
||||
-- subtraction implemented by adding ((not bv2) + 1), ie -bv2
|
||||
|
||||
alias op1 : bit_vector(1 to bv1'length) is bv1;
|
||||
alias op2 : bit_vector(1 to bv2'length) is bv2;
|
||||
variable result : bit_vector(1 to bv1'length);
|
||||
variable carry_in : bit;
|
||||
variable carry_out : bit := '1';
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length
|
||||
-- use concatenation to work around Synthesia MINT code gen bug
|
||||
report '"' & '-' & '"' & ": operands of different lengths"
|
||||
severity failure;
|
||||
for index in result'reverse_range loop
|
||||
carry_in := carry_out; -- of previous bit
|
||||
result(index) := op1(index) xor (not op2(index)) xor carry_in;
|
||||
carry_out := (op1(index) and (not op2(index)))
|
||||
or (carry_in and (op1(index) xor (not op2(index))));
|
||||
end loop;
|
||||
return result;
|
||||
end "-";
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_addu
|
||||
--
|
||||
-- Unsigned addition with overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
procedure bv_addu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
overflow : out boolean) is
|
||||
|
||||
alias op1 : bit_vector(1 to bv1'length) is bv1;
|
||||
alias op2 : bit_vector(1 to bv2'length) is bv2;
|
||||
variable result : bit_vector(1 to bv_result'length);
|
||||
variable carry : bit := '0';
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length and bv1'length = bv_result'length
|
||||
report "bv_addu: operands of different lengths"
|
||||
severity failure;
|
||||
for index in result'reverse_range loop
|
||||
result(index) := op1(index) xor op2(index) xor carry;
|
||||
carry := (op1(index) and op2(index))
|
||||
or (carry and (op1(index) xor op2(index)));
|
||||
end loop;
|
||||
bv_result := result;
|
||||
overflow := carry = '1';
|
||||
end bv_addu;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_addu
|
||||
--
|
||||
-- Unsigned addition without overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
procedure bv_addu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector) is
|
||||
|
||||
alias op1 : bit_vector(1 to bv1'length) is bv1;
|
||||
alias op2 : bit_vector(1 to bv2'length) is bv2;
|
||||
variable result : bit_vector(1 to bv_result'length);
|
||||
variable carry : bit := '0';
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length and bv1'length = bv_result'length
|
||||
report "bv_addu: operands of different lengths"
|
||||
severity failure;
|
||||
for index in result'reverse_range loop
|
||||
result(index) := op1(index) xor op2(index) xor carry;
|
||||
carry := (op1(index) and op2(index))
|
||||
or (carry and (op1(index) xor op2(index)));
|
||||
end loop;
|
||||
bv_result := result;
|
||||
end bv_addu;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_subu
|
||||
--
|
||||
-- Unsigned subtraction with overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
procedure bv_subu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
overflow : out boolean) is
|
||||
|
||||
alias op1 : bit_vector(1 to bv1'length) is bv1;
|
||||
alias op2 : bit_vector(1 to bv2'length) is bv2;
|
||||
variable result : bit_vector(1 to bv_result'length);
|
||||
variable borrow : bit := '0';
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length and bv1'length = bv_result'length
|
||||
report "bv_subu: operands of different lengths"
|
||||
severity failure;
|
||||
for index in result'reverse_range loop
|
||||
result(index) := op1(index) xor op2(index) xor borrow;
|
||||
borrow := (not op1(index) and op2(index))
|
||||
or (borrow and not (op1(index) xor op2(index)));
|
||||
end loop;
|
||||
bv_result := result;
|
||||
overflow := borrow = '1';
|
||||
end bv_subu;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_subu
|
||||
--
|
||||
-- Unsigned subtraction without overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
procedure bv_subu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector) is
|
||||
|
||||
alias op1 : bit_vector(1 to bv1'length) is bv1;
|
||||
alias op2 : bit_vector(1 to bv2'length) is bv2;
|
||||
variable result : bit_vector(1 to bv_result'length);
|
||||
variable borrow : bit := '0';
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length and bv1'length = bv_result'length
|
||||
report "bv_subu: operands of different lengths"
|
||||
severity failure;
|
||||
for index in result'reverse_range loop
|
||||
result(index) := op1(index) xor op2(index) xor borrow;
|
||||
borrow := (not op1(index) and op2(index))
|
||||
or (borrow and not (op1(index) xor op2(index)));
|
||||
end loop;
|
||||
bv_result := result;
|
||||
end bv_subu;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_neg
|
||||
--
|
||||
-- Signed negation with overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
procedure bv_neg (bv : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
overflow : out boolean) is
|
||||
|
||||
CONSTANT zero : bit_vector(bv'range) := (others => '0');
|
||||
|
||||
begin
|
||||
bv_sub( zero, bv, bv_result, overflow );
|
||||
end bv_neg;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- "-"
|
||||
--
|
||||
-- Signed negation without overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
function "-" (bv : in bit_vector) return bit_vector is
|
||||
|
||||
CONSTANT zero : bit_vector(bv'range) := (others => '0');
|
||||
|
||||
begin
|
||||
return zero - bv;
|
||||
end "-";
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_mult
|
||||
--
|
||||
-- Signed multiplication with overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
procedure bv_mult (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
overflow : out boolean) is
|
||||
|
||||
variable negative_result : boolean;
|
||||
variable op1 : bit_vector(bv1'range) := bv1;
|
||||
variable op2 : bit_vector(bv2'range) := bv2;
|
||||
variable multu_result : bit_vector(bv1'range);
|
||||
variable multu_overflow : boolean;
|
||||
-- constant abs_min_int : bit_vector(bv1'range)
|
||||
-- := (bv1'left => '1', others => '0');
|
||||
-- causes Synthesia MINT code generator to prang. Work around:
|
||||
variable abs_min_int : bit_vector(bv1'range) := (others => '0');
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length and bv1'length = bv_result'length
|
||||
report "bv_mult: operands of different lengths"
|
||||
severity failure;
|
||||
abs_min_int(bv1'left) := '1'; -- Synthesia work around
|
||||
negative_result := (op1(op1'left) = '1') xor (op2(op2'left) = '1');
|
||||
if (op1(op1'left) = '1') then
|
||||
op1 := - bv1;
|
||||
end if;
|
||||
if (op2(op2'left) = '1') then
|
||||
op2 := - bv2;
|
||||
end if;
|
||||
bv_multu(op1, op2, multu_result, multu_overflow);
|
||||
if (negative_result) then
|
||||
overflow := multu_overflow or (multu_result > abs_min_int);
|
||||
bv_result := - multu_result;
|
||||
else
|
||||
overflow := multu_overflow or (multu_result(multu_result'left) = '1');
|
||||
bv_result := multu_result;
|
||||
end if;
|
||||
end bv_mult;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- "*"
|
||||
--
|
||||
-- Signed multiplication without overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
function "*" (bv1, bv2 : in bit_vector) return bit_vector is
|
||||
|
||||
variable negative_result : boolean;
|
||||
variable op1 : bit_vector(bv1'range) := bv1;
|
||||
variable op2 : bit_vector(bv2'range) := bv2;
|
||||
variable result : bit_vector(bv1'range);
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length
|
||||
-- use concatenation to work around Synthesia MINT code gen bug
|
||||
report '"' & '*' & '"' & ": operands of different lengths"
|
||||
severity failure;
|
||||
negative_result := (op1(op1'left) = '1') xor (op2(op2'left) = '1');
|
||||
if (op1(op1'left) = '1') then
|
||||
op1 := - bv1;
|
||||
end if;
|
||||
if (op2(op2'left) = '1') then
|
||||
op2 := - bv2;
|
||||
end if;
|
||||
bv_multu(op1, op2, result);
|
||||
if (negative_result) then
|
||||
result := - result;
|
||||
end if;
|
||||
return result;
|
||||
end "*";
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_multu
|
||||
--
|
||||
-- Unsigned multiplication with overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
procedure bv_multu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
overflow : out boolean) is
|
||||
|
||||
-- Based on shift&add multiplier in Appendix A of Hennessy & Patterson
|
||||
|
||||
constant bv_length : natural := bv1'length;
|
||||
constant accum_length : natural := bv_length * 2;
|
||||
constant zero : bit_vector(accum_length-1 downto bv_length)
|
||||
:= (others => '0');
|
||||
variable accum : bit_vector(accum_length-1 downto 0);
|
||||
variable addu_overflow : boolean;
|
||||
variable carry : bit;
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length and bv1'length = bv_result'length
|
||||
report "bv_multu: operands of different lengths"
|
||||
severity failure;
|
||||
accum(bv_length-1 downto 0) := bv1;
|
||||
accum(accum_length-1 downto bv_length) := zero;
|
||||
for count in 1 to bv_length loop
|
||||
if (accum(0) = '1') then
|
||||
bv_addu( accum(accum_length-1 downto bv_length), bv2,
|
||||
accum(accum_length-1 downto bv_length), addu_overflow);
|
||||
carry := bit'val(boolean'pos(addu_overflow));
|
||||
else
|
||||
carry := '0';
|
||||
end if;
|
||||
accum := carry & accum(accum_length-1 downto 1);
|
||||
end loop;
|
||||
bv_result := accum(bv_length-1 downto 0);
|
||||
overflow := accum(accum_length-1 downto bv_length) /= zero;
|
||||
end bv_multu;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_multu
|
||||
--
|
||||
-- Unsigned multiplication without overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
procedure bv_multu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector) is
|
||||
|
||||
-- Use bv_multu with overflow detection, but ignore overflow flag
|
||||
|
||||
variable tmp_overflow : boolean;
|
||||
|
||||
begin
|
||||
-- following procedure asserts bv1'length = bv2'length
|
||||
bv_multu(bv1, bv2, bv_result, tmp_overflow);
|
||||
end bv_multu;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_div
|
||||
--
|
||||
-- Signed division with divide by zero and overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
procedure bv_div (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
div_by_zero : out boolean;
|
||||
overflow : out boolean) is
|
||||
|
||||
-- Need overflow, in case divide b"10...0" (min_int) by -1
|
||||
-- Don't use bv_to_int, in case size bigger than host machine!
|
||||
|
||||
variable negative_result : boolean;
|
||||
variable op1 : bit_vector(bv1'range) := bv1;
|
||||
variable op2 : bit_vector(bv2'range) := bv2;
|
||||
variable divu_result : bit_vector(bv1'range);
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length
|
||||
report "bv_div: operands of different lengths"
|
||||
severity failure;
|
||||
negative_result := (op1(op1'left) = '1') xor (op2(op2'left) = '1');
|
||||
if (op1(op1'left) = '1') then
|
||||
op1 := - bv1;
|
||||
end if;
|
||||
if (op2(op2'left) = '1') then
|
||||
op2 := - bv2;
|
||||
end if;
|
||||
bv_divu(op1, op2, divu_result, div_by_zero);
|
||||
if (negative_result) then
|
||||
overflow := false;
|
||||
bv_result := - divu_result;
|
||||
else
|
||||
overflow := divu_result(divu_result'left) = '1';
|
||||
bv_result := divu_result;
|
||||
end if;
|
||||
end bv_div;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- "/"
|
||||
--
|
||||
-- Signed division without divide by zero and overflow detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
function "/" (bv1, bv2 : in bit_vector) return bit_vector is
|
||||
|
||||
variable negative_result : boolean;
|
||||
variable op1 : bit_vector(bv1'range) := bv1;
|
||||
variable op2 : bit_vector(bv2'range) := bv2;
|
||||
variable result : bit_vector(bv1'range);
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length
|
||||
-- use concatenation to work around Synthesia MINT code gen bug
|
||||
report '"' & '/' & '"' & ": operands of different lengths"
|
||||
severity failure;
|
||||
negative_result := (op1(op1'left) = '1') xor (op2(op2'left) = '1');
|
||||
if (op1(op1'left) = '1') then
|
||||
op1 := - bv1;
|
||||
end if;
|
||||
if (op2(op2'left) = '1') then
|
||||
op2 := - bv2;
|
||||
end if;
|
||||
bv_divu(op1, op2, result);
|
||||
if (negative_result) then
|
||||
result := - result;
|
||||
end if;
|
||||
return result;
|
||||
end "/";
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_divu
|
||||
--
|
||||
-- Unsigned division with divide by zero detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
procedure bv_divu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
div_by_zero : out boolean) is
|
||||
|
||||
-- based on algorithm in Sun Sparc architecture manual
|
||||
|
||||
constant len : natural := bv1'length;
|
||||
variable zero, one,
|
||||
big_value : bit_vector(len-1 downto 0)
|
||||
:= (others => '0');
|
||||
variable dividend : bit_vector(bv1'length-1 downto 0) := bv1;
|
||||
variable divisor : bit_vector(bv2'length-1 downto 0) := bv2;
|
||||
variable quotient : bit_vector(len-1 downto 0); -- unsigned
|
||||
variable remainder : bit_vector(len-1 downto 0); -- signed
|
||||
variable shifted_divisor,
|
||||
shifted_1 : bit_vector(len-1 downto 0);
|
||||
variable log_quotient : natural;
|
||||
variable ignore_overflow : boolean;
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length
|
||||
report "bv_divu: operands of different lengths"
|
||||
severity failure;
|
||||
one(0) := '1';
|
||||
big_value(len-2) := '1';
|
||||
--
|
||||
-- check for zero divisor
|
||||
--
|
||||
if (divisor = zero) then
|
||||
div_by_zero := true;
|
||||
return;
|
||||
end if;
|
||||
--
|
||||
-- estimate log of quotient
|
||||
--
|
||||
log_quotient := 0;
|
||||
shifted_divisor := divisor;
|
||||
loop
|
||||
exit when (log_quotient >= len)
|
||||
or (shifted_divisor > big_value)
|
||||
or (shifted_divisor >= dividend);
|
||||
log_quotient := log_quotient + 1;
|
||||
shifted_divisor := bv_sll(shifted_divisor, 1);
|
||||
end loop;
|
||||
--
|
||||
-- perform division
|
||||
--
|
||||
remainder := dividend;
|
||||
quotient := zero;
|
||||
shifted_divisor := bv_sll(divisor, log_quotient);
|
||||
shifted_1 := bv_sll(one, log_quotient);
|
||||
for iter in log_quotient downto 0 loop
|
||||
if bv_ge(remainder, zero) then
|
||||
bv_sub(remainder, shifted_divisor, remainder, ignore_overflow);
|
||||
bv_addu(quotient, shifted_1, quotient, ignore_overflow);
|
||||
else
|
||||
bv_add(remainder, shifted_divisor, remainder, ignore_overflow);
|
||||
bv_subu(quotient, shifted_1, quotient, ignore_overflow);
|
||||
end if;
|
||||
shifted_divisor := '0' & shifted_divisor(len-1 downto 1);
|
||||
shifted_1 := '0' & shifted_1(len-1 downto 1);
|
||||
end loop;
|
||||
if (bv_lt(remainder, zero)) then
|
||||
bv_add(remainder, divisor, remainder, ignore_overflow);
|
||||
bv_subu(quotient, one, quotient, ignore_overflow);
|
||||
end if;
|
||||
bv_result := quotient;
|
||||
end bv_divu;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_divu
|
||||
--
|
||||
-- Unsigned division without divide by zero detection
|
||||
----------------------------------------------------------------
|
||||
|
||||
procedure bv_divu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector) is
|
||||
|
||||
-- Use bv_divu with divide by zero detection,
|
||||
-- but ignore div_by_zero flag
|
||||
|
||||
variable tmp_div_by_zero : boolean;
|
||||
|
||||
begin
|
||||
-- following procedure asserts bv1'length = bv2'length
|
||||
bv_divu(bv1, bv2, bv_result, tmp_div_by_zero);
|
||||
end bv_divu;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Logical operators
|
||||
-- (Provided for VHDL-87, built in for VHDL-93)
|
||||
----------------------------------------------------------------
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_sll
|
||||
--
|
||||
-- Shift left logical (fill with '0' bits)
|
||||
----------------------------------------------------------------
|
||||
|
||||
function bv_sll (bv : in bit_vector;
|
||||
shift_count : in natural) return bit_vector is
|
||||
|
||||
constant bv_length : natural := bv'length;
|
||||
constant actual_shift_count : natural := shift_count mod bv_length;
|
||||
alias bv_norm : bit_vector(1 to bv_length) is bv;
|
||||
variable result : bit_vector(1 to bv_length) := (others => '0');
|
||||
|
||||
begin
|
||||
result(1 to bv_length - actual_shift_count)
|
||||
:= bv_norm(actual_shift_count + 1 to bv_length);
|
||||
return result;
|
||||
end bv_sll;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_srl
|
||||
--
|
||||
-- Shift right logical (fill with '0' bits)
|
||||
----------------------------------------------------------------
|
||||
|
||||
function bv_srl (bv : in bit_vector;
|
||||
shift_count : in natural) return bit_vector is
|
||||
|
||||
constant bv_length : natural := bv'length;
|
||||
constant actual_shift_count : natural := shift_count mod bv_length;
|
||||
alias bv_norm : bit_vector(1 to bv_length) is bv;
|
||||
variable result : bit_vector(1 to bv_length) := (others => '0');
|
||||
|
||||
begin
|
||||
result(actual_shift_count + 1 to bv_length)
|
||||
:= bv_norm(1 to bv_length - actual_shift_count);
|
||||
return result;
|
||||
end bv_srl;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_sra
|
||||
--
|
||||
-- Shift right arithmetic (fill with copy of sign bit)
|
||||
----------------------------------------------------------------
|
||||
|
||||
|
||||
function bv_sra (bv : in bit_vector;
|
||||
shift_count : in natural) return bit_vector is
|
||||
|
||||
constant bv_length : natural := bv'length;
|
||||
constant actual_shift_count : natural := shift_count mod bv_length;
|
||||
alias bv_norm : bit_vector(1 to bv_length) is bv;
|
||||
variable result : bit_vector(1 to bv_length) := (others => bv(bv'left));
|
||||
|
||||
begin
|
||||
result(actual_shift_count + 1 to bv_length)
|
||||
:= bv_norm(1 to bv_length - actual_shift_count);
|
||||
return result;
|
||||
end bv_sra;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_rol
|
||||
--
|
||||
-- Rotate left
|
||||
----------------------------------------------------------------
|
||||
|
||||
function bv_rol (bv : in bit_vector;
|
||||
rotate_count : in natural) return bit_vector is
|
||||
|
||||
constant bv_length : natural := bv'length;
|
||||
constant actual_rotate_count : natural := rotate_count mod bv_length;
|
||||
alias bv_norm : bit_vector(1 to bv_length) is bv;
|
||||
variable result : bit_vector(1 to bv_length);
|
||||
|
||||
begin
|
||||
result(1 to bv_length - actual_rotate_count)
|
||||
:= bv_norm(actual_rotate_count + 1 to bv_length);
|
||||
result(bv_length - actual_rotate_count + 1 to bv_length)
|
||||
:= bv_norm(1 to actual_rotate_count);
|
||||
return result;
|
||||
end bv_rol;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_ror
|
||||
--
|
||||
-- Rotate right
|
||||
----------------------------------------------------------------
|
||||
|
||||
function bv_ror (bv : in bit_vector;
|
||||
rotate_count : in natural) return bit_vector is
|
||||
|
||||
constant bv_length : natural := bv'length;
|
||||
constant actual_rotate_count : natural := rotate_count mod bv_length;
|
||||
alias bv_norm : bit_vector(1 to bv_length) is bv;
|
||||
variable result : bit_vector(1 to bv_length);
|
||||
|
||||
begin
|
||||
result(actual_rotate_count + 1 to bv_length)
|
||||
:= bv_norm(1 to bv_length - actual_rotate_count);
|
||||
result(1 to actual_rotate_count)
|
||||
:= bv_norm(bv_length - actual_rotate_count + 1 to bv_length);
|
||||
return result;
|
||||
end bv_ror;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Arithmetic comparison operators.
|
||||
-- Perform comparisons on bit vector encoded signed integers.
|
||||
-- (For unsigned integers, built in lexical comparison does
|
||||
-- the required operation.)
|
||||
----------------------------------------------------------------
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_lt
|
||||
--
|
||||
-- Signed less than comparison
|
||||
----------------------------------------------------------------
|
||||
|
||||
function bv_lt (bv1, bv2 : in bit_vector) return boolean is
|
||||
|
||||
variable tmp1 : bit_vector(bv1'range) := bv1;
|
||||
variable tmp2 : bit_vector(bv2'range) := bv2;
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length
|
||||
report "bv_lt: operands of different lengths"
|
||||
severity failure;
|
||||
tmp1(tmp1'left) := not tmp1(tmp1'left);
|
||||
tmp2(tmp2'left) := not tmp2(tmp2'left);
|
||||
return tmp1 < tmp2;
|
||||
end bv_lt;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_le
|
||||
--
|
||||
-- Signed less than or equal comparison
|
||||
----------------------------------------------------------------
|
||||
|
||||
function bv_le (bv1, bv2 : in bit_vector) return boolean is
|
||||
|
||||
variable tmp1 : bit_vector(bv1'range) := bv1;
|
||||
variable tmp2 : bit_vector(bv2'range) := bv2;
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length
|
||||
report "bv_le: operands of different lengths"
|
||||
severity failure;
|
||||
tmp1(tmp1'left) := not tmp1(tmp1'left);
|
||||
tmp2(tmp2'left) := not tmp2(tmp2'left);
|
||||
return tmp1 <= tmp2;
|
||||
end bv_le;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_gt
|
||||
--
|
||||
-- Signed greater than comparison
|
||||
----------------------------------------------------------------
|
||||
|
||||
function bv_gt (bv1, bv2 : in bit_vector) return boolean is
|
||||
|
||||
variable tmp1 : bit_vector(bv1'range) := bv1;
|
||||
variable tmp2 : bit_vector(bv2'range) := bv2;
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length
|
||||
report "bv_gt: operands of different lengths"
|
||||
severity failure;
|
||||
tmp1(tmp1'left) := not tmp1(tmp1'left);
|
||||
tmp2(tmp2'left) := not tmp2(tmp2'left);
|
||||
return tmp1 > tmp2;
|
||||
end bv_gt;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_ge
|
||||
--
|
||||
-- Signed greater than or equal comparison
|
||||
----------------------------------------------------------------
|
||||
|
||||
function bv_ge (bv1, bv2 : in bit_vector) return boolean is
|
||||
|
||||
variable tmp1 : bit_vector(bv1'range) := bv1;
|
||||
variable tmp2 : bit_vector(bv2'range) := bv2;
|
||||
|
||||
begin
|
||||
assert bv1'length = bv2'length
|
||||
report "bv_ged: operands of different lengths"
|
||||
severity failure;
|
||||
tmp1(tmp1'left) := not tmp1(tmp1'left);
|
||||
tmp2(tmp2'left) := not tmp2(tmp2'left);
|
||||
return tmp1 >= tmp2;
|
||||
end bv_ge;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Extension operators - convert a bit vector to a longer one
|
||||
----------------------------------------------------------------
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_sext
|
||||
--
|
||||
-- Sign extension - replicate the sign bit of the operand into
|
||||
-- the most significant bits of the result. Length parameter
|
||||
-- determines size of result. If length < bv'length, result is
|
||||
-- rightmost length bits of bv.
|
||||
----------------------------------------------------------------
|
||||
|
||||
function bv_sext (bv : in bit_vector;
|
||||
length : in natural) return bit_vector is
|
||||
|
||||
alias bv_norm : bit_vector(1 to bv'length) is bv;
|
||||
variable result : bit_vector(1 to length) := (others => bv(bv'left));
|
||||
variable src_length : natural := bv'length;
|
||||
|
||||
begin
|
||||
if src_length > length then
|
||||
src_length := length;
|
||||
end if;
|
||||
result(length - src_length + 1 to length)
|
||||
:= bv_norm(bv'length - src_length + 1 to bv'length);
|
||||
return result;
|
||||
end bv_sext;
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- bv_zext
|
||||
--
|
||||
-- Zero extension - replicate zero bits into the most significant
|
||||
-- bits of the result. Length parameter determines size of result.
|
||||
-- If length < bv'length, result is rightmost length bits of bv.
|
||||
----------------------------------------------------------------
|
||||
|
||||
function bv_zext (bv : in bit_vector;
|
||||
length : in natural) return bit_vector is
|
||||
|
||||
alias bv_norm : bit_vector(1 to bv'length) is bv;
|
||||
variable result : bit_vector(1 to length) := (others => '0');
|
||||
variable src_length : natural := bv'length;
|
||||
|
||||
begin
|
||||
if src_length > length then
|
||||
src_length := length;
|
||||
end if;
|
||||
result(length - src_length + 1 to length)
|
||||
:= bv_norm(bv'length - src_length + 1 to bv'length);
|
||||
return result;
|
||||
end bv_zext;
|
||||
|
||||
|
||||
end bv_arithmetic;
|
||||
@@ -0,0 +1,238 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: bv_arithmetic.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 20:10:41 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Bit vector arithmetic package specification.
|
||||
--
|
||||
-- Does arithmetic and logical operations on bit vectors, treating them
|
||||
-- as either unsigned or signed (2's complement) integers. Leftmost bit
|
||||
-- is most significant or sign bit, rightmost bit is least significant
|
||||
-- bit. Dyadic operations need the two arguments to be of the same
|
||||
-- length, however their index ranges and directions may differ. Results
|
||||
-- must be of the same length as the operands.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
use std.textio.line;
|
||||
|
||||
package bv_arithmetic is
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Type conversions
|
||||
----------------------------------------------------------------
|
||||
|
||||
-- Convert bit vector encoded unsigned integer to natural.
|
||||
|
||||
function bv_to_natural (bv : in bit_vector) return natural;
|
||||
|
||||
-- Convert natural to bit vector encoded unsigned integer.
|
||||
-- (length is used as the size of the result.)
|
||||
|
||||
function natural_to_bv (nat : in natural;
|
||||
length : in natural) return bit_vector;
|
||||
|
||||
-- Convert bit vector encoded signed integer to integer
|
||||
|
||||
function bv_to_integer (bv : in bit_vector) return integer;
|
||||
|
||||
-- Convert integer to bit vector encoded signed integer.
|
||||
-- (length is used as the size of the result.)
|
||||
|
||||
function integer_to_bv (int : in integer;
|
||||
length : in natural) return bit_vector;
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Arithmetic operations
|
||||
----------------------------------------------------------------
|
||||
|
||||
-- Signed addition with overflow detection
|
||||
|
||||
procedure bv_add (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
overflow : out boolean);
|
||||
|
||||
-- Signed addition without overflow detection
|
||||
|
||||
function "+" (bv1, bv2 : in bit_vector) return bit_vector;
|
||||
|
||||
-- Signed subtraction with overflow detection
|
||||
|
||||
procedure bv_sub (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
overflow : out boolean);
|
||||
|
||||
-- Signed subtraction without overflow detection
|
||||
|
||||
function "-" (bv1, bv2 : in bit_vector) return bit_vector;
|
||||
|
||||
-- Unsigned addition with overflow detection
|
||||
|
||||
procedure bv_addu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
overflow : out boolean);
|
||||
|
||||
-- Unsigned addition without overflow detection
|
||||
|
||||
procedure bv_addu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector);
|
||||
|
||||
-- Unsigned subtraction with overflow detection
|
||||
|
||||
procedure bv_subu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
overflow : out boolean);
|
||||
|
||||
-- Unsigned subtraction without overflow detection
|
||||
|
||||
procedure bv_subu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector);
|
||||
|
||||
-- Signed negation with overflow detection
|
||||
|
||||
procedure bv_neg (bv : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
overflow : out boolean);
|
||||
|
||||
-- Signed negation without overflow detection
|
||||
|
||||
function "-" (bv : in bit_vector) return bit_vector;
|
||||
|
||||
-- Signed multiplication with overflow detection
|
||||
|
||||
procedure bv_mult (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
overflow : out boolean);
|
||||
|
||||
-- Signed multiplication without overflow detection
|
||||
|
||||
function "*" (bv1, bv2 : in bit_vector) return bit_vector;
|
||||
|
||||
-- Unsigned multiplication with overflow detection
|
||||
|
||||
procedure bv_multu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
overflow : out boolean);
|
||||
|
||||
-- Unsigned multiplication without overflow detection
|
||||
|
||||
procedure bv_multu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector);
|
||||
|
||||
-- Signed division with divide by zero and overflow detection
|
||||
|
||||
procedure bv_div (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
div_by_zero : out boolean;
|
||||
overflow : out boolean);
|
||||
|
||||
-- Signed division without divide by zero and overflow detection
|
||||
|
||||
function "/" (bv1, bv2 : in bit_vector) return bit_vector;
|
||||
|
||||
-- Unsigned division with divide by zero detection
|
||||
|
||||
procedure bv_divu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector;
|
||||
div_by_zero : out boolean);
|
||||
|
||||
-- Unsigned division without divide by zero detection
|
||||
|
||||
procedure bv_divu (bv1, bv2 : in bit_vector;
|
||||
bv_result : out bit_vector);
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Logical operators
|
||||
-- (Provided for VHDL-87, built in for VHDL-93)
|
||||
----------------------------------------------------------------
|
||||
|
||||
-- Shift left logical (fill with '0' bits)
|
||||
|
||||
function bv_sll (bv : in bit_vector;
|
||||
shift_count : in natural) return bit_vector;
|
||||
|
||||
-- Shift right logical (fill with '0' bits)
|
||||
|
||||
function bv_srl (bv : in bit_vector;
|
||||
shift_count : in natural) return bit_vector;
|
||||
|
||||
-- Shift right arithmetic (fill with copy of sign bit)
|
||||
|
||||
function bv_sra (bv : in bit_vector;
|
||||
shift_count : in natural) return bit_vector;
|
||||
|
||||
-- Rotate left
|
||||
|
||||
function bv_rol (bv : in bit_vector;
|
||||
rotate_count : in natural) return bit_vector;
|
||||
|
||||
-- Rotate right
|
||||
|
||||
function bv_ror (bv : in bit_vector;
|
||||
rotate_count : in natural) return bit_vector;
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Arithmetic comparison operators.
|
||||
-- Perform comparisons on bit vector encoded signed integers.
|
||||
-- (For unsigned integers, built in lexical comparison does
|
||||
-- the required operation.)
|
||||
----------------------------------------------------------------
|
||||
|
||||
-- Signed less than comparison
|
||||
|
||||
function bv_lt (bv1, bv2 : in bit_vector) return boolean;
|
||||
|
||||
-- Signed less than or equal comparison
|
||||
|
||||
function bv_le (bv1, bv2 : in bit_vector) return boolean;
|
||||
|
||||
-- Signed greater than comparison
|
||||
|
||||
function bv_gt (bv1, bv2 : in bit_vector) return boolean;
|
||||
|
||||
-- Signed greater than or equal comparison
|
||||
|
||||
function bv_ge (bv1, bv2 : in bit_vector) return boolean;
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Extension operators - convert a bit vector to a longer one
|
||||
----------------------------------------------------------------
|
||||
|
||||
-- Sign extension - replicate the sign bit of the operand into
|
||||
-- the most significant bits of the result. Length parameter
|
||||
-- determines size of result. If length < bv'length, result is
|
||||
-- rightmost length bits of bv.
|
||||
|
||||
function bv_sext (bv : in bit_vector;
|
||||
length : in natural) return bit_vector;
|
||||
|
||||
-- Zero extension - replicate zero bits into the most significant
|
||||
-- bits of the result. Length parameter determines size of result.
|
||||
-- If length < bv'length, result is rightmost length bits of bv.
|
||||
|
||||
function bv_zext (bv : in bit_vector;
|
||||
length : in natural) return bit_vector;
|
||||
|
||||
end bv_arithmetic;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: bv_test.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 20:12:11 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for test bench for bit vector arithmetic package.
|
||||
--
|
||||
|
||||
|
||||
entity bv_test is
|
||||
|
||||
begin
|
||||
|
||||
end bv_test;
|
||||
@@ -0,0 +1,310 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: cache-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 22:13:32 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture for cache.
|
||||
--
|
||||
|
||||
|
||||
use work.bv_arithmetic.bv_to_natural,
|
||||
work.bv_arithmetic.natural_to_bv;
|
||||
|
||||
|
||||
architecture behaviour of cache is
|
||||
|
||||
begin -- behaviour
|
||||
|
||||
cache_behaviour : process
|
||||
|
||||
constant words_per_line : positive := line_size / 4;
|
||||
constant number_of_sets : positive := cache_size / line_size / associativity;
|
||||
|
||||
subtype word_offset_range is natural range 0 to words_per_line-1;
|
||||
subtype entry_index_range is natural range 0 to associativity-1;
|
||||
subtype set_index_range is natural range 0 to number_of_sets-1;
|
||||
|
||||
type line is array (word_offset_range) of dlx_word;
|
||||
|
||||
type entry is record
|
||||
tag : natural;
|
||||
valid : boolean;
|
||||
dirty : boolean;
|
||||
data : line;
|
||||
end record;
|
||||
|
||||
type store_array is array (set_index_range, entry_index_range) of entry;
|
||||
|
||||
variable store : store_array;
|
||||
variable cpu_address : natural;
|
||||
variable word_offset : word_offset_range;
|
||||
variable set_index : set_index_range;
|
||||
variable cpu_tag : natural;
|
||||
variable entry_index : entry_index_range;
|
||||
variable hit : boolean;
|
||||
variable next_replacement_entry_index : entry_index_range := 0;
|
||||
|
||||
|
||||
procedure do_read_hit is
|
||||
begin
|
||||
cpu_d <= store(set_index, entry_index).data(word_offset);
|
||||
cpu_ready <= '1' after Tpd_clk_out;
|
||||
wait until phi2 = '0';
|
||||
cpu_d <= null after Tpd_clk_out;
|
||||
cpu_ready <= '0' after Tpd_clk_out;
|
||||
end do_read_hit;
|
||||
|
||||
|
||||
procedure do_write_through is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
mem_a <= cpu_a after Tpd_clk_out;
|
||||
mem_width <= cpu_width after Tpd_clk_out;
|
||||
mem_d <= cpu_d after Tpd_clk_out;
|
||||
mem_write <= '1' after Tpd_clk_out;
|
||||
mem_burst <= '0' after Tpd_clk_out;
|
||||
mem_enable <= '1' after Tpd_clk_out;
|
||||
wait until mem_ready = '1' or reset = '1';
|
||||
cpu_ready <= mem_ready after Tpd_clk_out;
|
||||
wait until phi2 = '0';
|
||||
mem_d <= null after Tpd_clk_out;
|
||||
mem_write <= '0' after Tpd_clk_out;
|
||||
mem_enable <= '0' after Tpd_clk_out;
|
||||
cpu_ready <= '0' after Tpd_clk_out;
|
||||
end do_write_through;
|
||||
|
||||
|
||||
procedure do_write_hit is
|
||||
begin
|
||||
case cpu_width is
|
||||
when width_word =>
|
||||
store(set_index, entry_index).data(word_offset) := cpu_d;
|
||||
when width_halfword =>
|
||||
if cpu_a(1) = '0' then -- ms half word
|
||||
store(set_index, entry_index).data(word_offset)(0 to 15) := cpu_d(0 to 15);
|
||||
else -- ls half word
|
||||
store(set_index, entry_index).data(word_offset)(16 to 23) := cpu_d(16 to 23);
|
||||
end if;
|
||||
when width_byte =>
|
||||
if cpu_a(1) = '0' then -- ms half word
|
||||
if cpu_a(0) = '0' then -- byte 0
|
||||
store(set_index, entry_index).data(word_offset)(0 to 7) := cpu_d(0 to 7);
|
||||
else -- byte 1
|
||||
store(set_index, entry_index).data(word_offset)(8 to 15) := cpu_d(8 to 15);
|
||||
end if;
|
||||
else -- ls half word
|
||||
if cpu_a(0) = '0' then -- byte 2
|
||||
store(set_index, entry_index).data(word_offset)(16 to 23) := cpu_d(16 to 23);
|
||||
else -- byte 3
|
||||
store(set_index, entry_index).data(word_offset)(24 to 31) := cpu_d(24 to 31);
|
||||
end if;
|
||||
end if;
|
||||
end case;
|
||||
if write_strategy = copy_back then
|
||||
store(set_index, entry_index).dirty := true;
|
||||
end if;
|
||||
--
|
||||
-- if write_through cache, also update main memory
|
||||
if write_strategy = write_through then
|
||||
do_write_through;
|
||||
else -- copy_back cache
|
||||
cpu_ready <= '1' after Tpd_clk_out;
|
||||
wait until phi2 = '0';
|
||||
cpu_ready <= '0' after Tpd_clk_out;
|
||||
end if;
|
||||
end do_write_hit;
|
||||
|
||||
|
||||
procedure copy_back_line is
|
||||
variable next_address : natural;
|
||||
variable old_word_offset : natural;
|
||||
begin
|
||||
next_address := (store(set_index, entry_index).tag * number_of_sets
|
||||
+ set_index) * line_size;
|
||||
wait until phi1 = '1';
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
mem_width <= width_word after Tpd_clk_out;
|
||||
mem_write <= '1' after Tpd_clk_out;
|
||||
mem_enable <= '1' after Tpd_clk_out;
|
||||
mem_burst <= '1' after Tpd_clk_out;
|
||||
old_word_offset := 0;
|
||||
burst_loop : loop
|
||||
if old_word_offset = words_per_line-1 then
|
||||
mem_burst <= '0' after Tpd_clk_out;
|
||||
end if;
|
||||
mem_a <= natural_to_bv(next_address, mem_a'length) after Tpd_clk_out;
|
||||
mem_d <= store(set_index, entry_index).data(old_word_offset) after Tpd_clk_out;
|
||||
wait_loop : loop
|
||||
wait until phi2 = '0';
|
||||
exit burst_loop when reset = '1'
|
||||
or (mem_ready = '1' and old_word_offset = words_per_line-1);
|
||||
exit wait_loop when mem_ready = '1';
|
||||
end loop wait_loop;
|
||||
old_word_offset := old_word_offset + 1;
|
||||
next_address := next_address + 4;
|
||||
end loop burst_loop;
|
||||
store(set_index, entry_index).dirty := false;
|
||||
mem_d <= null after Tpd_clk_out;
|
||||
mem_write <= '0' after Tpd_clk_out;
|
||||
mem_enable <= '0' after Tpd_clk_out;
|
||||
end copy_back_line;
|
||||
|
||||
|
||||
procedure fetch_line is
|
||||
variable next_address : natural;
|
||||
variable new_word_offset : natural;
|
||||
begin
|
||||
next_address := (cpu_address / line_size) * line_size;
|
||||
wait until phi1 = '1';
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
mem_width <= width_word after Tpd_clk_out;
|
||||
mem_write <= '0' after Tpd_clk_out;
|
||||
mem_enable <= '1' after Tpd_clk_out;
|
||||
mem_burst <= '1' after Tpd_clk_out;
|
||||
new_word_offset := 0;
|
||||
burst_loop : loop
|
||||
if new_word_offset = words_per_line-1 then
|
||||
mem_burst <= '0' after Tpd_clk_out;
|
||||
end if;
|
||||
mem_a <= natural_to_bv(next_address, mem_a'length) after Tpd_clk_out;
|
||||
wait_loop : loop
|
||||
wait until phi2 = '0';
|
||||
store(set_index, entry_index).data(new_word_offset) := mem_d;
|
||||
exit burst_loop when reset = '1'
|
||||
or (mem_ready = '1' and new_word_offset = words_per_line-1);
|
||||
exit wait_loop when mem_ready = '1';
|
||||
end loop wait_loop;
|
||||
new_word_offset := new_word_offset + 1;
|
||||
next_address := next_address + 4;
|
||||
end loop burst_loop;
|
||||
store(set_index, entry_index).valid := true;
|
||||
store(set_index, entry_index).tag := cpu_tag;
|
||||
store(set_index, entry_index).dirty := false;
|
||||
mem_enable <= '0' after Tpd_clk_out;
|
||||
end fetch_line;
|
||||
|
||||
|
||||
procedure replace_line is
|
||||
begin
|
||||
-- first chose an entry using "random" number generator
|
||||
entry_index := next_replacement_entry_index;
|
||||
next_replacement_entry_index
|
||||
:= (next_replacement_entry_index + 1) mod associativity;
|
||||
if store(set_index, entry_index).dirty then
|
||||
copy_back_line;
|
||||
end if;
|
||||
fetch_line;
|
||||
end replace_line;
|
||||
|
||||
|
||||
procedure do_read_miss is
|
||||
begin
|
||||
replace_line;
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
do_read_hit;
|
||||
end do_read_miss;
|
||||
|
||||
|
||||
procedure do_write_miss is
|
||||
begin
|
||||
-- if write_through cache, just update main memory
|
||||
if write_strategy = write_through then
|
||||
do_write_through;
|
||||
else -- copy_back cache
|
||||
replace_line;
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
do_write_hit;
|
||||
end if;
|
||||
end do_write_miss;
|
||||
|
||||
|
||||
begin -- process cache_behaviour
|
||||
-- reset: initialize outputs and the cache store valid bits
|
||||
cpu_ready <= '0';
|
||||
cpu_d <= null;
|
||||
mem_enable <= '0';
|
||||
mem_width <= width_word;
|
||||
mem_write <= '0';
|
||||
mem_burst <= '0';
|
||||
mem_a <= X"00000000";
|
||||
mem_d <= null;
|
||||
for init_set_index in set_index_range loop
|
||||
for init_entry_index in entry_index_range loop
|
||||
store(init_set_index, init_entry_index).valid := false;
|
||||
store(init_set_index, init_entry_index).dirty := false;
|
||||
end loop; -- init_entry_index
|
||||
end loop; -- init_set_index
|
||||
--
|
||||
loop
|
||||
-- wait for a cpu request
|
||||
wait until phi2 = '1' and cpu_enable = '1';
|
||||
-- decode address
|
||||
cpu_address := bv_to_natural(cpu_a);
|
||||
word_offset := (cpu_address mod line_size) / 4;
|
||||
set_index := (cpu_address / line_size) mod number_of_sets;
|
||||
cpu_tag := cpu_address / line_size / number_of_sets;
|
||||
-- check for hit
|
||||
hit := false;
|
||||
for lookup_entry_index in entry_index_range loop
|
||||
if store(set_index, lookup_entry_index).valid
|
||||
and store(set_index, lookup_entry_index).tag = cpu_tag then
|
||||
hit := true;
|
||||
entry_index := lookup_entry_index;
|
||||
exit;
|
||||
end if;
|
||||
end loop; -- lookup_entry
|
||||
--
|
||||
if hit then
|
||||
if cpu_write = '1' then
|
||||
do_write_hit;
|
||||
else
|
||||
do_read_hit;
|
||||
end if;
|
||||
else
|
||||
if cpu_write = '1' then
|
||||
do_write_miss;
|
||||
else
|
||||
do_read_miss;
|
||||
end if;
|
||||
end if;
|
||||
exit when reset = '1';
|
||||
end loop;
|
||||
-- loop exited on reset: wait until it goes inactive
|
||||
-- then start again
|
||||
wait until phi2 = '0' and reset = '0';
|
||||
end process cache_behaviour;
|
||||
|
||||
end behaviour;
|
||||
@@ -0,0 +1,61 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: cache.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 21:42:34 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for cache.
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_types.all,
|
||||
work.mem_types.all,
|
||||
work.cache_types.all;
|
||||
|
||||
entity cache is
|
||||
generic (cache_size : positive; -- in bytes, power of 2
|
||||
line_size : positive; -- in bytes, power of 2
|
||||
associativity : positive; -- 1 = direct mapped
|
||||
write_strategy : strategy_type; -- write_through or copy_back
|
||||
Tpd_clk_out : Time; -- clock to output propagation delay
|
||||
tag : string := "";
|
||||
origin_x, origin_y : real := 0.0);
|
||||
port (phi1, phi2 : in bit; -- 2-phase non-overlapping clocks
|
||||
reset : in bit; -- synchronous reset input
|
||||
-- connections to CPU
|
||||
cpu_enable : in bit; -- starts memory cycle
|
||||
cpu_width : in mem_width; -- byte/halfword/word indicator
|
||||
cpu_write : in bit; -- selects read or write cycle
|
||||
cpu_ready : out bit; -- status from memory system
|
||||
cpu_a : in dlx_address; -- address bus output
|
||||
cpu_d : inout dlx_word_bus bus; -- bidirectional data bus
|
||||
-- connections to memory
|
||||
mem_enable : out bit; -- starts memory cycle
|
||||
mem_width : out mem_width; -- byte/halfword/word indicator
|
||||
mem_write : out bit; -- selects read or write cycle
|
||||
mem_burst : out bit; -- tell memory to burst txfer
|
||||
mem_ready : in bit; -- status from memory system
|
||||
mem_a : out dlx_address; -- address bus output
|
||||
mem_d : inout dlx_word_bus bus); -- bidirectional data bus
|
||||
end cache;
|
||||
@@ -0,0 +1,36 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: cache_types.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 21:40:49 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Package spec defining types for cache.
|
||||
--
|
||||
|
||||
|
||||
package cache_types is
|
||||
|
||||
type strategy_type is (write_through, copy_back);
|
||||
|
||||
end cache_types;
|
||||
@@ -0,0 +1,48 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: clock_gen-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 20:29:05 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture body for clock generator
|
||||
--
|
||||
|
||||
|
||||
architecture behaviour of clock_gen is
|
||||
|
||||
constant clock_period : Time := 2*(Tpw+Tps);
|
||||
|
||||
begin
|
||||
|
||||
reset_driver:
|
||||
reset <= '1', '0' after 2*clock_period + Tpw+Tps;
|
||||
|
||||
clock_driver : process
|
||||
begin
|
||||
phi1 <= '1', '0' after Tpw;
|
||||
phi2 <= '1' after Tpw+Tps, '0' after Tpw+Tps+Tpw;
|
||||
wait for clock_period;
|
||||
end process clock_driver;
|
||||
|
||||
end behaviour;
|
||||
@@ -0,0 +1,42 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: clock_gen.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 20:20:50 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for clock generator
|
||||
--
|
||||
|
||||
|
||||
entity clock_gen is
|
||||
|
||||
generic (Tpw : Time; -- clock pulse width
|
||||
Tps : Time; -- clock pulse separation
|
||||
tag : string := "";
|
||||
origin_x, origin_y : real := 0.0);
|
||||
|
||||
port (phi1, phi2 : out bit; -- two-phase non-overlapping clocks
|
||||
reset : out bit); -- synchronous reset
|
||||
|
||||
end clock_gen;
|
||||
@@ -0,0 +1,50 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: clock_gen_test-bench.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 20:29:43 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Architecture for test bench for clock generator
|
||||
--
|
||||
|
||||
|
||||
architecture bench of clock_gen_test is
|
||||
|
||||
component clock_gen
|
||||
port (phi1, phi2 : out bit;
|
||||
reset : out bit);
|
||||
end component;
|
||||
|
||||
for cg : clock_gen
|
||||
use entity work.clock_gen(behaviour)
|
||||
generic map (Tpw => 8 ns, Tps => 2 ns);
|
||||
|
||||
signal p1, p2, reset : bit;
|
||||
|
||||
begin
|
||||
|
||||
cg : clock_gen
|
||||
port map (p1, p2, reset);
|
||||
|
||||
end bench;
|
||||
@@ -0,0 +1,33 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: clock_gen_test.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 20:29:32 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for test bench for clock generator
|
||||
--
|
||||
|
||||
|
||||
entity clock_gen_test is
|
||||
end clock_gen_test;
|
||||
@@ -0,0 +1,858 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: controller-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 21:36:38 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture of DLX control section.
|
||||
--
|
||||
|
||||
|
||||
use work.bv_arithmetic.all, std.textio.all;
|
||||
|
||||
architecture behaviour of controller is
|
||||
|
||||
begin -- behaviour
|
||||
|
||||
sequencer : process
|
||||
|
||||
alias IR_opcode : dlx_opcode is current_instruction(0 to 5);
|
||||
alias IR_sp_func : dlx_sp_func is current_instruction(26 to 31);
|
||||
alias IR_fp_func : dlx_fp_func is current_instruction(27 to 31);
|
||||
alias IR_rs1 : dlx_reg_addr is current_instruction(6 to 10);
|
||||
alias IR_rs2 : dlx_reg_addr is current_instruction(11 to 15);
|
||||
alias IR_Itype_rd : dlx_reg_addr is current_instruction(11 to 15);
|
||||
alias IR_Rtype_rd : dlx_reg_addr is current_instruction(16 to 20);
|
||||
alias IR_immed16 : dlx_immed16 is current_instruction(16 to 31);
|
||||
alias IR_immed26 : dlx_immed26 is current_instruction(6 to 31);
|
||||
|
||||
variable IR_opcode_num : dlx_opcode_num;
|
||||
variable IR_sp_func_num : dlx_sp_func_num;
|
||||
variable IR_fp_func_num : dlx_fp_func_num;
|
||||
|
||||
variable result_of_set_is_1, branch_taken : boolean;
|
||||
|
||||
variable L : line;
|
||||
|
||||
procedure bus_instruction_fetch is
|
||||
begin
|
||||
-- use PC as address
|
||||
mem_addr_mux_sel <= '0' after Tpd_clk_ctrl;
|
||||
-- set up memory control signals
|
||||
width <= width_word after Tpd_clk_ctrl;
|
||||
ifetch <= '1' after Tpd_clk_ctrl;
|
||||
mem_enable <= '1' after Tpd_clk_ctrl;
|
||||
-- wait until phi2, then enable IR input
|
||||
wait until phi2 = '1';
|
||||
ir_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
-- wait until memory is ready at end of phi2
|
||||
loop
|
||||
wait until phi2 = '0';
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
exit when ready = '1';
|
||||
end loop;
|
||||
-- disable IR input and memory control signals
|
||||
ir_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
mem_enable <= '0' after Tpd_clk_ctrl;
|
||||
end bus_instruction_fetch;
|
||||
|
||||
procedure bus_data_read(read_width : in mem_width) is
|
||||
begin
|
||||
-- use MAR as address
|
||||
mem_addr_mux_sel <= '1' after Tpd_clk_ctrl;
|
||||
-- set up memory control signals
|
||||
width <= read_width after Tpd_clk_ctrl;
|
||||
ifetch <= '0' after Tpd_clk_ctrl;
|
||||
mem_enable <= '1' after Tpd_clk_ctrl;
|
||||
-- wait until phi2, then enable MDR input
|
||||
wait until phi2 = '1';
|
||||
mdr_mux_sel <= '1' after Tpd_clk_ctrl;
|
||||
mdr_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
-- wait until memory is ready at end of phi2
|
||||
loop
|
||||
wait until phi2 = '0';
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
exit when ready = '1';
|
||||
end loop;
|
||||
-- disable MDR input and memory control signals
|
||||
mdr_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
mem_enable <= '0' after Tpd_clk_ctrl;
|
||||
end bus_data_read;
|
||||
|
||||
procedure bus_data_write(write_width : in mem_width) is
|
||||
begin
|
||||
-- use MAR as address
|
||||
mem_addr_mux_sel <= '1' after Tpd_clk_ctrl;
|
||||
-- enable MDR output
|
||||
mdr_out_en3 <= '1' after Tpd_clk_ctrl;
|
||||
-- set up memory control signals
|
||||
width <= write_width after Tpd_clk_ctrl;
|
||||
ifetch <= '0' after Tpd_clk_ctrl;
|
||||
write_enable <= '1' after Tpd_clk_ctrl;
|
||||
mem_enable <= '1' after Tpd_clk_ctrl;
|
||||
-- wait until memory is ready at end of phi2
|
||||
loop
|
||||
wait until phi2 = '0';
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
exit when ready = '1';
|
||||
end loop;
|
||||
-- disable MDR output and memory control signals
|
||||
write_enable <= '0' after Tpd_clk_ctrl;
|
||||
mem_enable <= '0' after Tpd_clk_ctrl;
|
||||
mdr_out_en3 <= '0' after Tpd_clk_ctrl;
|
||||
end bus_data_write;
|
||||
|
||||
procedure do_set_result is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
if result_of_set_is_1 then
|
||||
const2 <= X"0000_0001" after Tpd_clk_const;
|
||||
else
|
||||
const2 <= X"0000_0000" after Tpd_clk_const;
|
||||
end if;
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
alu_function <= alu_pass_s2 after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
const2 <= null after Tpd_clk_const;
|
||||
--
|
||||
wait until phi2 = '1';
|
||||
c_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
c_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
end do_set_result;
|
||||
|
||||
procedure do_EX_set_unsigned(immed : boolean) is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
a_out_en <= '1' after Tpd_clk_ctrl;
|
||||
if immed then
|
||||
ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl;
|
||||
ir_immed_unsigned2 <= '1' after Tpd_clk_ctrl;
|
||||
ir_immed_en2 <= '1' after Tpd_clk_ctrl;
|
||||
else
|
||||
b_out_en <= '1' after Tpd_clk_ctrl;
|
||||
end if;
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
alu_function <= alu_subu after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
a_out_en <= '0' after Tpd_clk_ctrl;
|
||||
if immed then
|
||||
ir_immed_en2 <= '0' after Tpd_clk_ctrl;
|
||||
else
|
||||
b_out_en <= '0' after Tpd_clk_ctrl;
|
||||
end if;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
if immed then
|
||||
case IR_opcode is
|
||||
when op_sequi =>
|
||||
result_of_set_is_1 := alu_zero = '1';
|
||||
when op_sneui =>
|
||||
result_of_set_is_1 := alu_zero /= '1';
|
||||
when op_sltui =>
|
||||
result_of_set_is_1 := alu_overflow = '1';
|
||||
when op_sgtui =>
|
||||
result_of_set_is_1 := alu_overflow /= '1' and alu_zero /= '1';
|
||||
when op_sleui =>
|
||||
result_of_set_is_1 := alu_overflow = '1' or alu_zero = '1';
|
||||
when op_sgeui =>
|
||||
result_of_set_is_1 := alu_overflow /= '1';
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
else
|
||||
case IR_sp_func is
|
||||
when sp_func_sequ =>
|
||||
result_of_set_is_1 := alu_zero = '1';
|
||||
when sp_func_sneu =>
|
||||
result_of_set_is_1 := alu_zero /= '1';
|
||||
when sp_func_sltu =>
|
||||
result_of_set_is_1 := alu_overflow = '1';
|
||||
when sp_func_sgtu =>
|
||||
result_of_set_is_1 := alu_overflow /= '1' and alu_zero /= '1';
|
||||
when sp_func_sleu =>
|
||||
result_of_set_is_1 := alu_overflow = '1' or alu_zero = '1';
|
||||
when sp_func_sgeu =>
|
||||
result_of_set_is_1 := alu_overflow /= '1';
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end if;
|
||||
--
|
||||
do_set_result;
|
||||
end do_EX_set_unsigned;
|
||||
|
||||
procedure do_EX_set_signed(immed : boolean) is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
a_out_en <= '1' after Tpd_clk_ctrl;
|
||||
if immed then
|
||||
ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl;
|
||||
ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl;
|
||||
ir_immed_en2 <= '1' after Tpd_clk_ctrl;
|
||||
else
|
||||
b_out_en <= '1' after Tpd_clk_ctrl;
|
||||
end if;
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
alu_function <= alu_sub after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
a_out_en <= '0' after Tpd_clk_ctrl;
|
||||
if immed then
|
||||
ir_immed_en2 <= '0' after Tpd_clk_ctrl;
|
||||
else
|
||||
b_out_en <= '0' after Tpd_clk_ctrl;
|
||||
end if;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
if immed then
|
||||
case IR_opcode is
|
||||
when op_seqi =>
|
||||
result_of_set_is_1 := alu_zero = '1';
|
||||
when op_snei =>
|
||||
result_of_set_is_1 := alu_zero /= '1';
|
||||
when op_slti =>
|
||||
result_of_set_is_1 := alu_negative = '1';
|
||||
when op_sgti =>
|
||||
result_of_set_is_1 := alu_negative /= '1' and alu_zero /= '1';
|
||||
when op_slei =>
|
||||
result_of_set_is_1 := alu_negative = '1' or alu_zero = '1';
|
||||
when op_sgei =>
|
||||
result_of_set_is_1 := alu_negative /= '1';
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
else
|
||||
case IR_sp_func is
|
||||
when sp_func_seq =>
|
||||
result_of_set_is_1 := alu_zero = '1';
|
||||
when sp_func_sne =>
|
||||
result_of_set_is_1 := alu_zero /= '1';
|
||||
when sp_func_slt =>
|
||||
result_of_set_is_1 := alu_negative = '1';
|
||||
when sp_func_sgt =>
|
||||
result_of_set_is_1 := alu_negative /= '1' and alu_zero /= '1';
|
||||
when sp_func_sle =>
|
||||
result_of_set_is_1 := alu_negative = '1' or alu_zero = '1';
|
||||
when sp_func_sge =>
|
||||
result_of_set_is_1 := alu_negative /= '1';
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end if;
|
||||
--
|
||||
do_set_result;
|
||||
end do_EX_set_signed;
|
||||
|
||||
procedure do_EX_arith_logic is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
a_out_en <= '1' after Tpd_clk_ctrl;
|
||||
b_out_en <= '1' after Tpd_clk_ctrl;
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
case IR_sp_func is
|
||||
when sp_func_add =>
|
||||
alu_function <= alu_add after Tpd_clk_ctrl;
|
||||
when sp_func_addu =>
|
||||
alu_function <= alu_addu after Tpd_clk_ctrl;
|
||||
when sp_func_sub =>
|
||||
alu_function <= alu_sub after Tpd_clk_ctrl;
|
||||
when sp_func_subu =>
|
||||
alu_function <= alu_subu after Tpd_clk_ctrl;
|
||||
when sp_func_and =>
|
||||
alu_function <= alu_and after Tpd_clk_ctrl;
|
||||
when sp_func_or =>
|
||||
alu_function <= alu_or after Tpd_clk_ctrl;
|
||||
when sp_func_xor =>
|
||||
alu_function <= alu_xor after Tpd_clk_ctrl;
|
||||
when sp_func_sll =>
|
||||
alu_function <= alu_sll after Tpd_clk_ctrl;
|
||||
when sp_func_srl =>
|
||||
alu_function <= alu_srl after Tpd_clk_ctrl;
|
||||
when sp_func_sra =>
|
||||
alu_function <= alu_sra after Tpd_clk_ctrl;
|
||||
when others =>
|
||||
null;
|
||||
end case; -- IR_sp_func
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
a_out_en <= '0' after Tpd_clk_ctrl;
|
||||
b_out_en <= '0' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '1';
|
||||
c_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
c_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
end do_EX_arith_logic;
|
||||
|
||||
procedure do_EX_arith_logic_immed is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
a_out_en <= '1' after Tpd_clk_ctrl;
|
||||
ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl;
|
||||
if IR_opcode = op_addi or IR_opcode = op_subi then
|
||||
ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl;
|
||||
else
|
||||
ir_immed_unsigned2 <= '1' after Tpd_clk_ctrl;
|
||||
end if;
|
||||
ir_immed_en2 <= '1' after Tpd_clk_ctrl;
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
case IR_opcode is
|
||||
when op_addi =>
|
||||
alu_function <= alu_add after Tpd_clk_ctrl;
|
||||
when op_subi =>
|
||||
alu_function <= alu_sub after Tpd_clk_ctrl;
|
||||
when op_addui =>
|
||||
alu_function <= alu_addu after Tpd_clk_ctrl;
|
||||
when op_subui =>
|
||||
alu_function <= alu_subu after Tpd_clk_ctrl;
|
||||
when op_andi =>
|
||||
alu_function <= alu_and after Tpd_clk_ctrl;
|
||||
when op_ori =>
|
||||
alu_function <= alu_or after Tpd_clk_ctrl;
|
||||
when op_xori =>
|
||||
alu_function <= alu_xor after Tpd_clk_ctrl;
|
||||
when op_slli =>
|
||||
alu_function <= alu_sll after Tpd_clk_ctrl;
|
||||
when op_srli =>
|
||||
alu_function <= alu_srl after Tpd_clk_ctrl;
|
||||
when op_srai =>
|
||||
alu_function <= alu_sra after Tpd_clk_ctrl;
|
||||
when others =>
|
||||
null;
|
||||
end case; -- IR_opcode
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
a_out_en <= '0' after Tpd_clk_ctrl;
|
||||
ir_immed_en2 <= '0' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '1';
|
||||
c_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
c_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
end do_EX_arith_logic_immed;
|
||||
|
||||
procedure do_EX_link is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
pc_out_en1 <= '1' after Tpd_clk_ctrl;
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
alu_function <= alu_pass_s1 after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
pc_out_en1 <= '0' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '1';
|
||||
c_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
c_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
end do_EX_link;
|
||||
|
||||
procedure do_EX_lhi is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
ir_immed_sel1 <= immed_size_16 after Tpd_clk_ctrl;
|
||||
ir_immed_unsigned1 <= '1' after Tpd_clk_ctrl;
|
||||
ir_immed_en1 <= '1' after Tpd_clk_ctrl;
|
||||
const2 <= X"0000_0010" after Tpd_clk_const; -- shift by 16 bits
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
alu_function <= alu_sll after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
ir_immed_en1 <= '0' after Tpd_clk_ctrl;
|
||||
const2 <= null after Tpd_clk_const;
|
||||
--
|
||||
wait until phi2 = '1';
|
||||
c_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
c_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
end do_EX_lhi;
|
||||
|
||||
procedure do_EX_branch is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
a_out_en <= '1' after Tpd_clk_ctrl;
|
||||
const2 <= X"0000_0000" after Tpd_clk_const;
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
alu_function <= alu_sub after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
a_out_en <= '0' after Tpd_clk_ctrl;
|
||||
const2 <= null after Tpd_clk_const;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
if IR_opcode = op_beqz then
|
||||
branch_taken := alu_zero = '1';
|
||||
else
|
||||
branch_taken := alu_zero /= '1';
|
||||
end if;
|
||||
end do_EX_branch;
|
||||
|
||||
procedure do_EX_load_store is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
a_out_en <= '1' after Tpd_clk_ctrl;
|
||||
ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl;
|
||||
ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl;
|
||||
ir_immed_en2 <= '1' after Tpd_clk_ctrl;
|
||||
alu_function <= alu_add after Tpd_clk_ctrl;
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
a_out_en <= '0' after Tpd_clk_ctrl;
|
||||
ir_immed_en2 <= '0' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '1';
|
||||
mar_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
mar_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
end do_EX_load_store;
|
||||
|
||||
procedure do_MEM_jump is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
pc_out_en1 <= '1' after Tpd_clk_ctrl;
|
||||
ir_immed_sel2 <= immed_size_26 after Tpd_clk_ctrl;
|
||||
ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl;
|
||||
ir_immed_en2 <= '1' after Tpd_clk_ctrl;
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
alu_function <= alu_add after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
pc_out_en1 <= '0' after Tpd_clk_ctrl;
|
||||
ir_immed_en2 <= '0' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '1';
|
||||
pc_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
pc_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
end do_MEM_jump;
|
||||
|
||||
procedure do_MEM_jump_reg is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
a_out_en <= '1' after Tpd_clk_ctrl;
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
alu_function <= alu_pass_s1 after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
a_out_en <= '0' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '1';
|
||||
pc_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
pc_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
end do_MEM_jump_reg;
|
||||
|
||||
procedure do_MEM_branch is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
pc_out_en1 <= '1' after Tpd_clk_ctrl;
|
||||
ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl;
|
||||
ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl;
|
||||
ir_immed_en2 <= '1' after Tpd_clk_ctrl;
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
alu_function <= alu_add after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
pc_out_en1 <= '0' after Tpd_clk_ctrl;
|
||||
ir_immed_en2 <= '0' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '1';
|
||||
pc_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
pc_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
end do_MEM_branch;
|
||||
|
||||
procedure do_MEM_load is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
bus_data_read(width_word);
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
--
|
||||
wait until phi1 = '1';
|
||||
mdr_out_en1 <= '1' after Tpd_clk_ctrl;
|
||||
alu_function <= alu_pass_s1 after Tpd_clk_ctrl;
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
mdr_out_en1 <= '0' after Tpd_clk_ctrl;
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '1';
|
||||
c_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
c_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
end do_MEM_load;
|
||||
|
||||
procedure do_MEM_store is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
b_out_en <= '1' after Tpd_clk_ctrl;
|
||||
alu_function <= alu_pass_s2 after Tpd_clk_ctrl;
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
b_out_en <= '0' after Tpd_clk_ctrl;
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '1';
|
||||
mdr_mux_sel <= '0' after Tpd_clk_ctrl;
|
||||
mdr_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
mdr_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi1 = '1';
|
||||
bus_data_write(width_word);
|
||||
end do_MEM_store;
|
||||
|
||||
procedure do_WB(Rd : dlx_reg_addr) is
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
reg_dest_addr <= Rd after Tpd_clk_ctrl;
|
||||
reg_write <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
reg_write <= '0' after Tpd_clk_ctrl;
|
||||
end do_WB;
|
||||
|
||||
|
||||
begin -- sequencer
|
||||
--
|
||||
----------------------------------------------------------------
|
||||
-- initialize all control signals
|
||||
----------------------------------------------------------------
|
||||
if debug then
|
||||
write(L, string'("controller: initializing"));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
--
|
||||
halt <= '0' after Tpd_clk_ctrl;
|
||||
width <= width_word after Tpd_clk_ctrl;
|
||||
write_enable <= '0' after Tpd_clk_ctrl;
|
||||
mem_enable <= '0' after Tpd_clk_ctrl;
|
||||
ifetch <= '0' after Tpd_clk_ctrl;
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
alu_function <= alu_add after Tpd_clk_ctrl;
|
||||
reg_s1_addr <= B"00000" after Tpd_clk_ctrl;
|
||||
reg_s2_addr <= B"00000" after Tpd_clk_ctrl;
|
||||
reg_dest_addr <= B"00000" after Tpd_clk_ctrl;
|
||||
reg_write <= '0' after Tpd_clk_ctrl;
|
||||
c_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
a_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
a_out_en <= '0' after Tpd_clk_ctrl;
|
||||
b_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
b_out_en <= '0' after Tpd_clk_ctrl;
|
||||
temp_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
temp_out_en1 <= '0' after Tpd_clk_ctrl;
|
||||
temp_out_en2 <= '0' after Tpd_clk_ctrl;
|
||||
iar_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
iar_out_en1 <= '0' after Tpd_clk_ctrl;
|
||||
iar_out_en2 <= '0' after Tpd_clk_ctrl;
|
||||
pc_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
pc_out_en1 <= '0' after Tpd_clk_ctrl;
|
||||
pc_out_en2 <= '0' after Tpd_clk_ctrl;
|
||||
mar_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
mar_out_en1 <= '0' after Tpd_clk_ctrl;
|
||||
mar_out_en2 <= '0' after Tpd_clk_ctrl;
|
||||
mem_addr_mux_sel <= '0' after Tpd_clk_ctrl;
|
||||
mdr_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
mdr_out_en1 <= '0' after Tpd_clk_ctrl;
|
||||
mdr_out_en2 <= '0' after Tpd_clk_ctrl;
|
||||
mdr_out_en3 <= '0' after Tpd_clk_ctrl;
|
||||
mdr_mux_sel <= '0' after Tpd_clk_ctrl;
|
||||
ir_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
ir_immed_sel1 <= immed_size_16 after Tpd_clk_ctrl;
|
||||
ir_immed_sel2 <= immed_size_16 after Tpd_clk_ctrl;
|
||||
ir_immed_unsigned1 <= '0' after Tpd_clk_ctrl;
|
||||
ir_immed_unsigned2 <= '0' after Tpd_clk_ctrl;
|
||||
ir_immed_en1 <= '0' after Tpd_clk_ctrl;
|
||||
ir_immed_en2 <= '0' after Tpd_clk_ctrl;
|
||||
const1 <= null after Tpd_clk_const;
|
||||
const2 <= null after Tpd_clk_const;
|
||||
--
|
||||
wait until phi2 = '0' and reset = '0';
|
||||
--
|
||||
----------------------------------------------------------------
|
||||
-- control loop
|
||||
----------------------------------------------------------------
|
||||
loop
|
||||
--
|
||||
----------------------------------------------------------------
|
||||
-- fetch next instruction (IF)
|
||||
----------------------------------------------------------------
|
||||
wait until phi1 = '1';
|
||||
if debug then
|
||||
write(L, string'("controller: instruction fetch"));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
--
|
||||
bus_instruction_fetch;
|
||||
--
|
||||
----------------------------------------------------------------
|
||||
-- instruction decode, source register read, and PC increment (ID)
|
||||
----------------------------------------------------------------
|
||||
wait until phi1 = '1';
|
||||
if debug then
|
||||
write(L, string'("controller: decode, reg-read and PC incr"));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
--
|
||||
IR_opcode_num := bv_to_natural(IR_opcode);
|
||||
IR_sp_func_num := bv_to_natural(IR_sp_func);
|
||||
IR_fp_func_num := bv_to_natural(IR_fp_func);
|
||||
--
|
||||
reg_s1_addr <= IR_rs1 after Tpd_clk_ctrl;
|
||||
reg_s2_addr <= IR_rs2 after Tpd_clk_ctrl;
|
||||
a_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
b_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
pc_out_en1 <= '1' after Tpd_clk_ctrl;
|
||||
const2 <= X"0000_0004" after Tpd_clk_const;
|
||||
alu_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
alu_function <= alu_addu after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi1 = '0';
|
||||
a_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
b_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
alu_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
pc_out_en1 <= '0' after Tpd_clk_ctrl;
|
||||
const2 <= null after Tpd_clk_const;
|
||||
--
|
||||
wait until phi2 = '1';
|
||||
pc_latch_en <= '1' after Tpd_clk_ctrl;
|
||||
--
|
||||
wait until phi2 = '0';
|
||||
pc_latch_en <= '0' after Tpd_clk_ctrl;
|
||||
--
|
||||
----------------------------------------------------------------
|
||||
-- execute instruction, (EX, MEM, WB)
|
||||
----------------------------------------------------------------
|
||||
if debug then
|
||||
write(L, string'("controller: execute"));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
--
|
||||
case IR_opcode is
|
||||
when op_special =>
|
||||
case IR_sp_func is
|
||||
when sp_func_nop =>
|
||||
null;
|
||||
when sp_func_sequ | sp_func_sneu |
|
||||
sp_func_sltu | sp_func_sgtu |
|
||||
sp_func_sleu | sp_func_sgeu =>
|
||||
do_EX_set_unsigned(immed => false);
|
||||
do_WB(IR_Rtype_rd);
|
||||
when sp_func_add | sp_func_addu |
|
||||
sp_func_sub | sp_func_subu |
|
||||
sp_func_and | sp_func_or | sp_func_xor |
|
||||
sp_func_sll | sp_func_srl | sp_func_sra =>
|
||||
do_EX_arith_logic;
|
||||
do_WB(IR_Rtype_rd);
|
||||
when sp_func_seq | sp_func_sne |
|
||||
sp_func_slt | sp_func_sgt |
|
||||
sp_func_sle | sp_func_sge =>
|
||||
do_EX_set_signed(immed => false);
|
||||
do_WB(IR_Rtype_rd);
|
||||
when sp_func_movi2s =>
|
||||
assert false
|
||||
report "MOVI2S instruction not implemented" severity warning;
|
||||
when sp_func_movs2i =>
|
||||
assert false
|
||||
report "MOVS2I instruction not implemented" severity warning;
|
||||
when sp_func_movf =>
|
||||
assert false
|
||||
report "MOVF instruction not implemented" severity warning;
|
||||
when sp_func_movd =>
|
||||
assert false
|
||||
report "MOVD instruction not implemented" severity warning;
|
||||
when sp_func_movfp2i =>
|
||||
assert false
|
||||
report "MOVFP2I instruction not implemented" severity warning;
|
||||
when sp_func_movi2fp =>
|
||||
assert false
|
||||
report "MOVI2FP instruction not implemented" severity warning;
|
||||
when others =>
|
||||
assert false
|
||||
report "undefined special instruction function" severity error;
|
||||
end case;
|
||||
when op_fparith =>
|
||||
case IR_fp_func is
|
||||
when fp_func_addf | fp_func_subf | fp_func_multf | fp_func_divf |
|
||||
fp_func_addd | fp_func_subd | fp_func_multd | fp_func_divd |
|
||||
fp_func_mult | fp_func_multu | fp_func_div | fp_func_divu |
|
||||
fp_func_cvtf2d | fp_func_cvtf2i | fp_func_cvtd2f |
|
||||
fp_func_cvtd2i | fp_func_cvti2f | fp_func_cvti2d |
|
||||
fp_func_eqf | fp_func_nef | fp_func_ltf | fp_func_gtf |
|
||||
fp_func_lef | fp_func_gef | fp_func_eqd | fp_func_ned |
|
||||
fp_func_ltd | fp_func_gtd | fp_func_led | fp_func_ged =>
|
||||
assert false
|
||||
report "floating point instructions not implemented" severity warning;
|
||||
when others =>
|
||||
assert false
|
||||
report "undefined floating point instruction function" severity error;
|
||||
end case;
|
||||
when op_j =>
|
||||
do_MEM_jump;
|
||||
when op_jr =>
|
||||
do_MEM_jump_reg;
|
||||
when op_jal =>
|
||||
do_EX_link;
|
||||
do_MEM_jump;
|
||||
do_WB(natural_to_bv(link_reg, 5));
|
||||
when op_jalr =>
|
||||
do_EX_link;
|
||||
do_MEM_jump_reg;
|
||||
do_WB(natural_to_bv(link_reg, 5));
|
||||
when op_beqz | op_bnez =>
|
||||
do_EX_branch;
|
||||
if branch_taken then
|
||||
do_MEM_branch;
|
||||
end if;
|
||||
when op_bfpt =>
|
||||
assert false
|
||||
report "BFPT instruction not implemented" severity warning;
|
||||
when op_bfpf =>
|
||||
assert false
|
||||
report "BFPF instruction not implemented" severity warning;
|
||||
when op_addi | op_subi |
|
||||
op_addui | op_subui |
|
||||
op_andi | op_ori | op_xori |
|
||||
op_slli | op_srli | op_srai =>
|
||||
do_EX_arith_logic_immed;
|
||||
do_WB(IR_Itype_rd);
|
||||
when op_lhi =>
|
||||
do_EX_lhi;
|
||||
do_WB(IR_Itype_rd);
|
||||
when op_rfe =>
|
||||
assert false
|
||||
report "RFE instruction not implemented" severity warning;
|
||||
when op_trap =>
|
||||
assert false
|
||||
report "TRAP instruction encountered, execution halted"
|
||||
severity note;
|
||||
wait until phi1 = '1';
|
||||
halt <= '1' after Tpd_clk_ctrl;
|
||||
wait until reset = '1';
|
||||
exit;
|
||||
when op_seqi | op_snei | op_slti |
|
||||
op_sgti | op_slei | op_sgei =>
|
||||
do_EX_set_signed(immed => true);
|
||||
do_WB(IR_Itype_rd);
|
||||
when op_lb =>
|
||||
assert false
|
||||
report "LB instruction not implemented" severity warning;
|
||||
when op_lh =>
|
||||
assert false
|
||||
report "LH instruction not implemented" severity warning;
|
||||
when op_lw =>
|
||||
do_EX_load_store;
|
||||
do_MEM_load;
|
||||
exit when reset = '1';
|
||||
do_WB(IR_Itype_rd);
|
||||
when op_sw =>
|
||||
do_EX_load_store;
|
||||
do_MEM_store;
|
||||
exit when reset = '1';
|
||||
when op_lbu =>
|
||||
assert false
|
||||
report "LBU instruction not implemented" severity warning;
|
||||
when op_lhu =>
|
||||
assert false
|
||||
report "LHU instruction not implemented" severity warning;
|
||||
when op_sb =>
|
||||
assert false
|
||||
report "SB instruction not implemented" severity warning;
|
||||
when op_sh =>
|
||||
assert false
|
||||
report "SH instruction not implemented" severity warning;
|
||||
when op_lf =>
|
||||
assert false
|
||||
report "LF instruction not implemented" severity warning;
|
||||
when op_ld =>
|
||||
assert false
|
||||
report "LD instruction not implemented" severity warning;
|
||||
when op_sf =>
|
||||
assert false
|
||||
report "SF instruction not implemented" severity warning;
|
||||
when op_sd =>
|
||||
assert false
|
||||
report "SD instruction not implemented" severity warning;
|
||||
when op_sequi | op_sneui | op_sltui |
|
||||
op_sgtui | op_sleui | op_sgeui =>
|
||||
do_EX_set_unsigned(immed => true);
|
||||
do_WB(IR_Itype_rd);
|
||||
when others =>
|
||||
assert false
|
||||
report "undefined instruction" severity error;
|
||||
end case;
|
||||
--
|
||||
end loop;
|
||||
--
|
||||
----------------------------------------------------------------
|
||||
-- loop exited on reset
|
||||
----------------------------------------------------------------
|
||||
assert reset = '1'
|
||||
report "Internal error: reset code reached with reset = '0'"
|
||||
severity failure;
|
||||
--
|
||||
-- start again
|
||||
--
|
||||
end process sequencer;
|
||||
|
||||
|
||||
end behaviour;
|
||||
@@ -0,0 +1,71 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: controller.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 19:19:52 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for DLX control section.
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_types.all,
|
||||
work.dlx_instr.all,
|
||||
work.alu_types.all,
|
||||
work.mem_types.all;
|
||||
|
||||
entity controller is
|
||||
generic (Tpd_clk_ctrl, Tpd_clk_const : Time;
|
||||
debug : boolean := false;
|
||||
tag : string := "";
|
||||
origin_x, origin_y : real := 0.0);
|
||||
port (phi1, phi2 : in bit;
|
||||
reset : in bit;
|
||||
halt : out bit;
|
||||
width : out mem_width;
|
||||
write_enable : out bit;
|
||||
mem_enable : out bit;
|
||||
ifetch : out bit;
|
||||
ready : in bit;
|
||||
alu_latch_en : out bit;
|
||||
alu_function : out alu_func;
|
||||
alu_zero, alu_negative, alu_overflow : in bit;
|
||||
reg_s1_addr, reg_s2_addr, reg_dest_addr : out dlx_reg_addr;
|
||||
reg_write : out bit;
|
||||
c_latch_en : out bit;
|
||||
a_latch_en, a_out_en : out bit;
|
||||
b_latch_en, b_out_en : out bit;
|
||||
temp_latch_en, temp_out_en1, temp_out_en2 : out bit;
|
||||
iar_latch_en, iar_out_en1, iar_out_en2 : out bit;
|
||||
pc_latch_en, pc_out_en1, pc_out_en2 : out bit;
|
||||
mar_latch_en, mar_out_en1, mar_out_en2 : out bit;
|
||||
mem_addr_mux_sel : out bit;
|
||||
mdr_latch_en, mdr_out_en1, mdr_out_en2, mdr_out_en3 : out bit;
|
||||
mdr_mux_sel : out bit;
|
||||
ir_latch_en : out bit;
|
||||
ir_immed_sel1, ir_immed_sel2 : out immed_size;
|
||||
ir_immed_unsigned1, ir_immed_unsigned2 : out bit;
|
||||
ir_immed_en1, ir_immed_en2 : out bit;
|
||||
current_instruction : in dlx_word;
|
||||
const1, const2 : out dlx_word_bus bus);
|
||||
end controller;
|
||||
@@ -0,0 +1,63 @@
|
||||
distribution-manifest
|
||||
README
|
||||
module-directory
|
||||
simple.s
|
||||
test_loop.s
|
||||
images.vhdl
|
||||
images-body.vhdl
|
||||
images_test.vhdl
|
||||
images_test-bench.vhdl
|
||||
bv_arithmetic.vhdl
|
||||
bv_arithmetic-body.vhdl
|
||||
bv_test.vhdl
|
||||
bv_test-bench.vhdl
|
||||
clock_gen.vhdl
|
||||
clock_gen-behaviour.vhdl
|
||||
clock_gen_test.vhdl
|
||||
clock_gen_test-bench.vhdl
|
||||
dlx_types.vhdl
|
||||
dlx_types-body.vhdl
|
||||
mem_types.vhdl
|
||||
memory.vhdl
|
||||
memory-behaviour.vhdl
|
||||
memory_test.vhdl
|
||||
memory_test-bench.vhdl
|
||||
dlx_instr.vhdl
|
||||
dlx_instr-body.vhdl
|
||||
dlx_bus_monitor.vhdl
|
||||
dlx_bus_monitor-behaviour.vhdl
|
||||
dlx_test.vhdl
|
||||
dlx_test-bench.vhdl
|
||||
dlx.vhdl
|
||||
dlx-behaviour.vhdl
|
||||
dlx_test_behaviour.vhdl
|
||||
dlx-instrumented.vhdl
|
||||
dlx_test_instrumented.vhdl
|
||||
alu_types.vhdl
|
||||
alu.vhdl
|
||||
alu-behaviour.vhdl
|
||||
ir.vhdl
|
||||
ir-behaviour.vhdl
|
||||
latch.vhdl
|
||||
latch-behaviour.vhdl
|
||||
mux2.vhdl
|
||||
mux2-behaviour.vhdl
|
||||
reg_1_out.vhdl
|
||||
reg_1_out-behaviour.vhdl
|
||||
reg_2_1_out.vhdl
|
||||
reg_2_1_out-behaviour.vhdl
|
||||
reg_2_out.vhdl
|
||||
reg_2_out-behaviour.vhdl
|
||||
reg_3_out.vhdl
|
||||
reg_3_out-behaviour.vhdl
|
||||
reg_file.vhdl
|
||||
reg_file-behaviour.vhdl
|
||||
controller.vhdl
|
||||
controller-behaviour.vhdl
|
||||
dlx-rtl.vhdl
|
||||
dlx_test_rtl.vhdl
|
||||
cache_types.vhdl
|
||||
cache.vhdl
|
||||
cache-behaviour.vhdl
|
||||
dlx_test-bench_cache.vhdl
|
||||
dlx_test_cache.vhdl
|
||||
@@ -0,0 +1,614 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 17:59:40 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture for DLX processor
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_instr.all,
|
||||
work.bv_arithmetic.all,
|
||||
std.textio.all;
|
||||
|
||||
|
||||
architecture behaviour of dlx is
|
||||
|
||||
begin -- behaviour
|
||||
|
||||
interpreter: process
|
||||
|
||||
type reg_array is array (reg_index) of dlx_word;
|
||||
|
||||
variable reg : reg_array;
|
||||
variable fp_reg : reg_array;
|
||||
|
||||
variable PC : dlx_word;
|
||||
variable user_mode : boolean;
|
||||
variable overflow, div_by_zero : boolean;
|
||||
|
||||
constant PC_incr : dlx_word := X"0000_0004";
|
||||
|
||||
variable IR : dlx_word;
|
||||
alias IR_opcode : dlx_opcode is IR(0 to 5);
|
||||
alias IR_sp_func : dlx_sp_func is IR(26 to 31);
|
||||
alias IR_fp_func : dlx_fp_func is IR(27 to 31);
|
||||
alias IR_rs1 : dlx_reg_addr is IR(6 to 10);
|
||||
alias IR_rs2 : dlx_reg_addr is IR(11 to 15);
|
||||
alias IR_Itype_rd : dlx_reg_addr is IR(11 to 15);
|
||||
alias IR_Rtype_rd : dlx_reg_addr is IR(16 to 20);
|
||||
alias IR_immed16 : dlx_immed16 is IR(16 to 31);
|
||||
alias IR_immed26 : dlx_immed26 is IR(6 to 31);
|
||||
|
||||
variable IR_opcode_num : dlx_opcode_num;
|
||||
variable IR_sp_func_num : dlx_sp_func_num;
|
||||
variable IR_fp_func_num : dlx_fp_func_num;
|
||||
variable rs1, rs2, Itype_rd, Rtype_rd : reg_index;
|
||||
variable mem_addr : dlx_address;
|
||||
variable mem_data : dlx_word;
|
||||
|
||||
subtype ls_2_addr_bits is bit_vector(1 downto 0);
|
||||
|
||||
variable L : line;
|
||||
|
||||
|
||||
procedure write (address : in dlx_address;
|
||||
data_width : in mem_width;
|
||||
data : in dlx_word;
|
||||
signal phi1, phi2 : in bit; -- 2-phase non-overlapping clks
|
||||
signal reset : in bit; -- synchronous reset input
|
||||
signal a : out dlx_address; -- address bus output
|
||||
signal d : inout dlx_word_bus; -- bidirectional data bus
|
||||
signal width : out mem_width; -- byte/halfword/word
|
||||
signal write_enable : out bit; -- selects read/write cycle
|
||||
signal mem_enable : out bit; -- starts memory cycle
|
||||
signal ifetch : out bit; -- indicates instruction fetch
|
||||
signal ready : in bit; -- status from memory system
|
||||
Tpd_clk_out : in time -- clock to output delay
|
||||
) is
|
||||
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
a <= address after Tpd_clk_out;
|
||||
width <= data_width after Tpd_clk_out;
|
||||
d <= data after Tpd_clk_out;
|
||||
write_enable <= '1' after Tpd_clk_out;
|
||||
mem_enable <= '1' after Tpd_clk_out;
|
||||
ifetch <= '0' after Tpd_clk_out;
|
||||
loop
|
||||
wait until phi2 = '0';
|
||||
exit when ready = '1' or reset = '1';
|
||||
end loop;
|
||||
d <= null after Tpd_clk_out;
|
||||
write_enable <= '0' after Tpd_clk_out;
|
||||
mem_enable <= '0' after Tpd_clk_out;
|
||||
end write;
|
||||
|
||||
|
||||
procedure bus_read (address : in dlx_address;
|
||||
data_width : in mem_width;
|
||||
instr_fetch : in boolean;
|
||||
data : out dlx_word;
|
||||
signal phi1, phi2 : in bit; -- 2-phase non-overlapping clks
|
||||
signal reset : in bit; -- synchronous reset input
|
||||
signal a : out dlx_address; -- address bus output
|
||||
signal d : inout dlx_word_bus; -- bidirectional data bus
|
||||
signal width : out mem_width; -- byte/halfword/word
|
||||
signal write_enable : out bit; -- selects read/write cycle
|
||||
signal mem_enable : out bit; -- starts memory cycle
|
||||
signal ifetch : out bit; -- indicates instruction eftch
|
||||
signal ready : in bit; -- status from memory system
|
||||
Tpd_clk_out : in time -- clock to output delay
|
||||
) is
|
||||
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
a <= address after Tpd_clk_out;
|
||||
width <= data_width after Tpd_clk_out;
|
||||
mem_enable <= '1' after Tpd_clk_out;
|
||||
ifetch <= bit'val(boolean'pos(instr_fetch)) after Tpd_clk_out;
|
||||
loop
|
||||
wait until phi2 = '0';
|
||||
exit when ready = '1' or reset = '1';
|
||||
end loop;
|
||||
data := d;
|
||||
mem_enable <= '0' after Tpd_clk_out;
|
||||
end bus_read;
|
||||
|
||||
|
||||
begin -- interpreter
|
||||
--
|
||||
-- reset the processor
|
||||
--
|
||||
d <= null;
|
||||
halt <= '0';
|
||||
write_enable <= '0';
|
||||
mem_enable <= '0';
|
||||
reg(0) := X"0000_0000";
|
||||
PC := X"0000_0000";
|
||||
user_mode := false;
|
||||
--
|
||||
-- fetch-decode-execute loop
|
||||
--
|
||||
loop
|
||||
--
|
||||
-- fetch next instruction
|
||||
--
|
||||
if debug then
|
||||
write(L, tag);
|
||||
write(L, string'(": fetching instruction..."));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
--
|
||||
bus_read(PC, width_word, true, IR,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
--
|
||||
-- increment the PC to point to the following instruction
|
||||
--
|
||||
if debug then
|
||||
write(L, tag);
|
||||
write(L, string'(": incrementing PC..."));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
--
|
||||
bv_add(PC, PC_incr, PC, overflow);
|
||||
--
|
||||
-- decode the instruction
|
||||
--
|
||||
if debug then
|
||||
write(L, tag);
|
||||
write(L, string'(": decoding instruction..."));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
--
|
||||
IR_opcode_num := bv_to_natural(IR_opcode);
|
||||
IR_sp_func_num := bv_to_natural(IR_sp_func);
|
||||
IR_fp_func_num := bv_to_natural(IR_fp_func);
|
||||
rs1 := bv_to_natural(IR_rs1);
|
||||
rs2 := bv_to_natural(IR_rs2);
|
||||
Itype_rd := bv_to_natural(IR_Itype_rd);
|
||||
Rtype_rd := bv_to_natural(IR_Rtype_rd);
|
||||
--
|
||||
-- exectute
|
||||
--
|
||||
if debug then
|
||||
write(L, tag);
|
||||
write(L, string'(": executing instruction..."));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
--
|
||||
case IR_opcode is
|
||||
when op_special =>
|
||||
case IR_sp_func is
|
||||
WHEN sp_func_nop =>
|
||||
null;
|
||||
when sp_func_sll =>
|
||||
reg(Rtype_rd) := bv_sll(reg(rs1), bv_to_natural(reg(rs2)(27 to 31)));
|
||||
when sp_func_srl =>
|
||||
reg(Rtype_rd) := bv_srl(reg(rs1), bv_to_natural(reg(rs2)(27 to 31)));
|
||||
when sp_func_sra =>
|
||||
reg(Rtype_rd) := bv_sra(reg(rs1), bv_to_natural(reg(rs2)(27 to 31)));
|
||||
when sp_func_sequ =>
|
||||
if reg(rs1) = reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sneu =>
|
||||
if reg(rs1) /= reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sltu =>
|
||||
if reg(rs1) < reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sgtu =>
|
||||
if reg(rs1) > reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sleu =>
|
||||
if reg(rs1) <= reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sgeu =>
|
||||
if reg(rs1) >= reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_add =>
|
||||
bv_add(reg(rs1), reg(rs2), reg(Rtype_rd), overflow);
|
||||
when sp_func_addu =>
|
||||
bv_addu(reg(rs1), reg(rs2), reg(Rtype_rd), overflow);
|
||||
when sp_func_sub =>
|
||||
bv_sub(reg(rs1), reg(rs2), reg(Rtype_rd), overflow);
|
||||
when sp_func_subu =>
|
||||
bv_subu(reg(rs1), reg(rs2), reg(Rtype_rd), overflow);
|
||||
when sp_func_and =>
|
||||
reg(Rtype_rd) := reg(rs1) and reg(rs2);
|
||||
when sp_func_or =>
|
||||
reg(Rtype_rd) := reg(rs1) or reg(rs2);
|
||||
when sp_func_xor =>
|
||||
reg(Rtype_rd) := reg(rs1) xor reg(rs2);
|
||||
when sp_func_seq =>
|
||||
if reg(rs1) = reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sne =>
|
||||
if reg(rs1) /= reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_slt =>
|
||||
if bv_lt(reg(rs1), reg(rs2)) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sgt =>
|
||||
if bv_gt(reg(rs1), reg(rs2)) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sle =>
|
||||
if bv_le(reg(rs1), reg(rs2)) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sge =>
|
||||
if bv_ge(reg(rs1), reg(rs2)) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_movi2s =>
|
||||
assert false
|
||||
report "MOVI2S instruction not implemented" severity warning;
|
||||
when sp_func_movs2i =>
|
||||
assert false
|
||||
report "MOVS2I instruction not implemented" severity warning;
|
||||
when sp_func_movf =>
|
||||
assert false
|
||||
report "MOVF instruction not implemented" severity warning;
|
||||
when sp_func_movd =>
|
||||
assert false
|
||||
report "MOVD instruction not implemented" severity warning;
|
||||
when sp_func_movfp2i =>
|
||||
reg(Rtype_rd) := fp_reg(rs1);
|
||||
when sp_func_movi2fp =>
|
||||
fp_reg(Rtype_rd) := reg(rs1);
|
||||
when others =>
|
||||
assert false
|
||||
report "undefined special instruction function" severity error;
|
||||
end case;
|
||||
when op_fparith =>
|
||||
case IR_fp_func is
|
||||
when fp_func_mult =>
|
||||
bv_mult(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), overflow);
|
||||
when fp_func_multu =>
|
||||
bv_multu(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), overflow);
|
||||
when fp_func_div =>
|
||||
bv_div(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), div_by_zero, overflow);
|
||||
when fp_func_divu =>
|
||||
bv_divu(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), div_by_zero);
|
||||
when fp_func_addf | fp_func_subf | fp_func_multf | fp_func_divf |
|
||||
fp_func_addd | fp_func_subd | fp_func_multd | fp_func_divd |
|
||||
fp_func_cvtf2d | fp_func_cvtf2i | fp_func_cvtd2f |
|
||||
fp_func_cvtd2i | fp_func_cvti2f | fp_func_cvti2d |
|
||||
fp_func_eqf | fp_func_nef | fp_func_ltf | fp_func_gtf |
|
||||
fp_func_lef | fp_func_gef | fp_func_eqd | fp_func_ned |
|
||||
fp_func_ltd | fp_func_gtd | fp_func_led | fp_func_ged =>
|
||||
assert false
|
||||
report "floating point instructions not implemented" severity warning;
|
||||
when others =>
|
||||
assert false
|
||||
report "undefined floating point instruction function" severity error;
|
||||
end case;
|
||||
when op_j =>
|
||||
bv_add(PC, bv_sext(IR_immed26, 32), PC, overflow);
|
||||
when op_jal =>
|
||||
reg(link_reg) := PC;
|
||||
bv_add(PC, bv_sext(IR_immed26, 32), PC, overflow);
|
||||
when op_beqz =>
|
||||
if reg(rs1) = X"0000_0000" then
|
||||
bv_add(PC, bv_sext(IR_immed16, 32), PC, overflow);
|
||||
end if;
|
||||
when op_bnez =>
|
||||
if reg(rs1) /= X"0000_0000" then
|
||||
bv_add(PC, bv_sext(IR_immed16, 32), PC, overflow);
|
||||
end if;
|
||||
when op_bfpt =>
|
||||
assert false
|
||||
report "BFPT instruction not implemented" severity warning;
|
||||
when op_bfpf =>
|
||||
assert false
|
||||
report "BFPF instruction not implemented" severity warning;
|
||||
when op_addi =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), reg(Itype_rd), overflow);
|
||||
when op_addui =>
|
||||
bv_addu(reg(rs1), bv_zext(IR_immed16, 32), reg(Itype_rd), overflow);
|
||||
when op_subi =>
|
||||
bv_sub(reg(rs1), bv_sext(IR_immed16, 32), reg(Itype_rd), overflow);
|
||||
when op_subui =>
|
||||
bv_subu(reg(rs1), bv_zext(IR_immed16, 32), reg(Itype_rd), overflow);
|
||||
when op_slli =>
|
||||
reg(Itype_rd) := bv_sll(reg(rs1), bv_to_natural(IR_immed16(11 to 15)));
|
||||
when op_srli =>
|
||||
reg(Itype_rd) := bv_srl(reg(rs1), bv_to_natural(IR_immed16(11 to 15)));
|
||||
when op_srai =>
|
||||
reg(Itype_rd) := bv_sra(reg(rs1), bv_to_natural(IR_immed16(11 to 15)));
|
||||
when op_andi =>
|
||||
reg(Itype_rd) := reg(rs1) and bv_zext(IR_immed16, 32);
|
||||
when op_ori =>
|
||||
reg(Itype_rd) := reg(rs1) or bv_zext(IR_immed16, 32);
|
||||
when op_xori =>
|
||||
reg(Itype_rd) := reg(rs1) xor bv_zext(IR_immed16, 32);
|
||||
when op_lhi =>
|
||||
reg(Itype_rd) := IR_immed16 & X"0000";
|
||||
when op_rfe =>
|
||||
assert false
|
||||
report "RFE instruction not implemented" severity warning;
|
||||
when op_trap =>
|
||||
assert false
|
||||
report "TRAP instruction encountered, execution halted"
|
||||
severity note;
|
||||
halt <= '1' after Tpd_clk_out;
|
||||
wait until reset = '1';
|
||||
exit;
|
||||
when op_jr =>
|
||||
PC := reg(rs1);
|
||||
when op_jalr =>
|
||||
reg(link_reg) := PC;
|
||||
PC := reg(rs1);
|
||||
when op_seqi =>
|
||||
if reg(rs1) = bv_sext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_snei =>
|
||||
if reg(rs1) /= bv_sext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_slti =>
|
||||
if bv_lt(reg(rs1), bv_sext(IR_immed16, 32)) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_sgti =>
|
||||
if bv_gt(reg(rs1), bv_sext(IR_immed16, 32)) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_slei =>
|
||||
if bv_le(reg(rs1), bv_sext(IR_immed16, 32)) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_sgei =>
|
||||
if bv_ge(reg(rs1), bv_sext(IR_immed16, 32)) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_lb =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
bus_read(mem_addr, width_byte, false, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
case ls_2_addr_bits'(mem_addr(1 downto 0)) is
|
||||
when B"00" =>
|
||||
reg(Itype_rd) := bv_sext(mem_data(0 to 7), 32);
|
||||
when B"01" =>
|
||||
reg(Itype_rd) := bv_sext(mem_data(8 to 15), 32);
|
||||
when B"10" =>
|
||||
reg(Itype_rd) := bv_sext(mem_data(16 to 23), 32);
|
||||
when B"11" =>
|
||||
reg(Itype_rd) := bv_sext(mem_data(24 to 31), 32);
|
||||
end case;
|
||||
when op_lh =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
bus_read(mem_addr, width_halfword, false, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
if mem_addr(1) = '0' then
|
||||
reg(Itype_rd) := bv_sext(mem_data(0 to 15), 32);
|
||||
else
|
||||
reg(Itype_rd) := bv_sext(mem_data(16 to 31), 32);
|
||||
end if;
|
||||
when op_lw =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
bus_read(mem_addr, width_word, false, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
reg(Itype_rd) := mem_data;
|
||||
when op_lbu =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
bus_read(mem_addr, width_byte, false, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
case ls_2_addr_bits'(mem_addr(1 downto 0)) is
|
||||
when B"00" =>
|
||||
reg(Itype_rd) := bv_zext(mem_data(0 to 7), 32);
|
||||
when B"01" =>
|
||||
reg(Itype_rd) := bv_zext(mem_data(8 to 15), 32);
|
||||
when B"10" =>
|
||||
reg(Itype_rd) := bv_zext(mem_data(16 to 23), 32);
|
||||
when B"11" =>
|
||||
reg(Itype_rd) := bv_zext(mem_data(24 to 31), 32);
|
||||
end case;
|
||||
when op_lhu =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
bus_read(mem_addr, width_halfword, false, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
if mem_addr(1) = '0' then
|
||||
reg(Itype_rd) := bv_zext(mem_data(0 to 15), 32);
|
||||
else
|
||||
reg(Itype_rd) := bv_zext(mem_data(16 to 31), 32);
|
||||
end if;
|
||||
when op_lf =>
|
||||
assert false
|
||||
report "LF instruction not implemented" severity warning;
|
||||
when op_ld =>
|
||||
assert false
|
||||
report "LD instruction not implemented" severity warning;
|
||||
when op_sb =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
mem_data := X"0000_0000";
|
||||
case ls_2_addr_bits'(mem_addr(1 downto 0)) is
|
||||
when B"00" =>
|
||||
mem_data(0 to 7) := reg(Itype_rd)(0 to 7);
|
||||
when B"01" =>
|
||||
mem_data(8 to 15) := reg(Itype_rd)(0 to 7);
|
||||
when B"10" =>
|
||||
mem_data(16 to 23) := reg(Itype_rd)(0 to 7);
|
||||
when B"11" =>
|
||||
mem_data(24 to 31) := reg(Itype_rd)(0 to 7);
|
||||
end case;
|
||||
write(mem_addr, width_halfword, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
when op_sh =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
mem_data := X"0000_0000";
|
||||
if mem_addr(1) = '0' then
|
||||
mem_data(0 to 15) := reg(Itype_rd)(0 to 15);
|
||||
else
|
||||
mem_data(16 to 31) := reg(Itype_rd)(0 to 15);
|
||||
end if;
|
||||
write(mem_addr, width_halfword, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
when op_sw =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
mem_data := reg(Itype_rd);
|
||||
write(mem_addr, width_word, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
when op_sf =>
|
||||
assert false
|
||||
report "SF instruction not implemented" severity warning;
|
||||
when op_sd =>
|
||||
assert false
|
||||
report "SD instruction not implemented" severity warning;
|
||||
when op_sequi =>
|
||||
if reg(rs1) = bv_zext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_sneui =>
|
||||
if reg(rs1) /= bv_zext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_sltui =>
|
||||
if reg(rs1) < bv_zext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_sgtui =>
|
||||
if reg(rs1) > bv_zext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_sleui =>
|
||||
if reg(rs1) <= bv_zext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_sgeui =>
|
||||
if reg(rs1) >= bv_zext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when others =>
|
||||
assert false
|
||||
report "undefined instruction" severity error;
|
||||
end case;
|
||||
--
|
||||
-- fix up R0 in case it was overwritten
|
||||
--
|
||||
reg(0) := X"0000_0000";
|
||||
--
|
||||
if debug then
|
||||
write(L, tag);
|
||||
write(L, string'(": end of execution"));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
--
|
||||
end loop;
|
||||
--
|
||||
-- loop is only exited when reset active: wait until it goes inactive
|
||||
--
|
||||
assert reset = '1'
|
||||
report "reset code reached with reset = '0'" severity error;
|
||||
wait until phi2 = '0' and reset = '0';
|
||||
--
|
||||
-- process interpreter now starts again from beginning
|
||||
--
|
||||
end process interpreter;
|
||||
|
||||
end behaviour;
|
||||
@@ -0,0 +1,687 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx-instrumented.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 18:36:01 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Instrumented behavioural architecture for DLX, that generates
|
||||
-- a files of instruction execution frequencies for a program.
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_instr.all,
|
||||
work.bv_arithmetic.all,
|
||||
std.textio.all;
|
||||
|
||||
|
||||
architecture instrumented of dlx is
|
||||
|
||||
begin -- instrumented
|
||||
|
||||
interpreter: process
|
||||
|
||||
type reg_array is array (reg_index) of dlx_word;
|
||||
|
||||
variable reg : reg_array;
|
||||
variable fp_reg : reg_array;
|
||||
|
||||
variable PC : dlx_word;
|
||||
variable user_mode : boolean;
|
||||
variable overflow, div_by_zero : boolean;
|
||||
|
||||
constant PC_incr : dlx_word := X"0000_0004";
|
||||
|
||||
variable IR : dlx_word;
|
||||
alias IR_opcode : dlx_opcode is IR(0 to 5);
|
||||
alias IR_sp_func : dlx_sp_func is IR(26 to 31);
|
||||
alias IR_fp_func : dlx_fp_func is IR(27 to 31);
|
||||
alias IR_rs1 : dlx_reg_addr is IR(6 to 10);
|
||||
alias IR_rs2 : dlx_reg_addr is IR(11 to 15);
|
||||
alias IR_Itype_rd : dlx_reg_addr is IR(11 to 15);
|
||||
alias IR_Rtype_rd : dlx_reg_addr is IR(16 to 20);
|
||||
alias IR_immed16 : dlx_immed16 is IR(16 to 31);
|
||||
alias IR_immed26 : dlx_immed26 is IR(6 to 31);
|
||||
|
||||
variable IR_opcode_num : dlx_opcode_num;
|
||||
variable IR_sp_func_num : dlx_sp_func_num;
|
||||
variable IR_fp_func_num : dlx_fp_func_num;
|
||||
variable rs1, rs2, Itype_rd, Rtype_rd : reg_index;
|
||||
variable mem_addr : dlx_address;
|
||||
variable mem_data : dlx_word;
|
||||
|
||||
subtype ls_2_addr_bits is bit_vector(1 downto 0);
|
||||
|
||||
file data : text is out "dlx_instruction_counts";
|
||||
|
||||
variable L : line;
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- instrumentation: array of counters, one per instruction
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
type opcode_count_array is array (dlx_opcode_num) of natural;
|
||||
type sp_func_count_array is array (dlx_sp_func_num) of natural;
|
||||
type fp_func_count_array is array (dlx_fp_func_num) of natural;
|
||||
|
||||
variable op_count : opcode_count_array := (others => 0);
|
||||
variable sp_func_count : sp_func_count_array := (others => 0);
|
||||
variable fp_func_count : fp_func_count_array := (others => 0);
|
||||
|
||||
variable instr_count : natural := 0;
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- instrumentation: procedure to dump counter values
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
procedure instrumentation_dump is
|
||||
variable L : line;
|
||||
begin
|
||||
for op in dlx_opcode_num loop
|
||||
write(L, opcode_names(op));
|
||||
write(L, ' ');
|
||||
write(L, op_count(op));
|
||||
writeline(data, L);
|
||||
end loop;
|
||||
for sp_func in dlx_sp_func_num loop
|
||||
write(L, sp_func_names(sp_func));
|
||||
write(L, ' ');
|
||||
write(L, sp_func_count(sp_func));
|
||||
writeline(data, L);
|
||||
end loop;
|
||||
for fp_func in dlx_fp_func_num loop
|
||||
write(L, fp_func_names(fp_func));
|
||||
write(L, ' ');
|
||||
write(L, fp_func_count(fp_func));
|
||||
writeline(data, L);
|
||||
end loop;
|
||||
end instrumentation_dump;
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
||||
procedure write (address : in dlx_address;
|
||||
data_width : in mem_width;
|
||||
data : in dlx_word;
|
||||
signal phi1, phi2 : in bit; -- 2-phase non-overlapping clks
|
||||
signal reset : in bit; -- synchronous reset input
|
||||
signal a : out dlx_address; -- address bus output
|
||||
signal d : inout dlx_word_bus; -- bidirectional data bus
|
||||
signal width : out mem_width; -- byte/halfword/word
|
||||
signal write_enable : out bit; -- selects read/write cycle
|
||||
signal mem_enable : out bit; -- starts memory cycle
|
||||
signal ifetch : out bit; -- indicates instruction fetch
|
||||
signal ready : in bit; -- status from memory system
|
||||
Tpd_clk_out : in time -- clock to output delay
|
||||
) is
|
||||
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
a <= address after Tpd_clk_out;
|
||||
width <= data_width after Tpd_clk_out;
|
||||
d <= data after Tpd_clk_out;
|
||||
write_enable <= '1' after Tpd_clk_out;
|
||||
mem_enable <= '1' after Tpd_clk_out;
|
||||
ifetch <= '0' after Tpd_clk_out;
|
||||
loop
|
||||
wait until phi2 = '0';
|
||||
exit when ready = '1' or reset = '1';
|
||||
end loop;
|
||||
d <= null after Tpd_clk_out;
|
||||
write_enable <= '0' after Tpd_clk_out;
|
||||
mem_enable <= '0' after Tpd_clk_out;
|
||||
end write;
|
||||
|
||||
|
||||
procedure bus_read (address : in dlx_address;
|
||||
data_width : in mem_width;
|
||||
instr_fetch : in boolean;
|
||||
data : out dlx_word;
|
||||
signal phi1, phi2 : in bit; -- 2-phase non-overlapping clks
|
||||
signal reset : in bit; -- synchronous reset input
|
||||
signal a : out dlx_address; -- address bus output
|
||||
signal d : inout dlx_word_bus; -- bidirectional data bus
|
||||
signal width : out mem_width; -- byte/halfword/word
|
||||
signal write_enable : out bit; -- selects read/write cycle
|
||||
signal mem_enable : out bit; -- starts memory cycle
|
||||
signal ifetch : out bit; -- indicates instruction eftch
|
||||
signal ready : in bit; -- status from memory system
|
||||
Tpd_clk_out : in time -- clock to output delay
|
||||
) is
|
||||
|
||||
begin
|
||||
wait until phi1 = '1';
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
a <= address after Tpd_clk_out;
|
||||
width <= data_width after Tpd_clk_out;
|
||||
mem_enable <= '1' after Tpd_clk_out;
|
||||
ifetch <= bit'val(boolean'pos(instr_fetch)) after Tpd_clk_out;
|
||||
loop
|
||||
wait until phi2 = '0';
|
||||
exit when ready = '1' or reset = '1';
|
||||
end loop;
|
||||
data := d;
|
||||
mem_enable <= '0' after Tpd_clk_out;
|
||||
end bus_read;
|
||||
|
||||
|
||||
begin -- interpreter
|
||||
--
|
||||
-- reset the processor
|
||||
--
|
||||
d <= null;
|
||||
halt <= '0';
|
||||
write_enable <= '0';
|
||||
mem_enable <= '0';
|
||||
reg(0) := X"0000_0000";
|
||||
PC := X"0000_0000";
|
||||
user_mode := false;
|
||||
--
|
||||
-- fetch-decode-execute loop
|
||||
--
|
||||
loop
|
||||
--
|
||||
-- fetch next instruction
|
||||
--
|
||||
if debug then
|
||||
write(L, tag);
|
||||
write(L, string'(": fetching instruction..."));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
--
|
||||
bus_read(PC, width_word, true, IR,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
--
|
||||
-- increment the PC to point to the following instruction
|
||||
--
|
||||
if debug then
|
||||
write(L, tag);
|
||||
write(L, string'(": incrementing PC..."));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
--
|
||||
bv_add(PC, PC_incr, PC, overflow);
|
||||
--
|
||||
-- decode the instruction
|
||||
--
|
||||
if debug then
|
||||
write(L, tag);
|
||||
write(L, string'(": decoding instruction..."));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
--
|
||||
IR_opcode_num := bv_to_natural(IR_opcode);
|
||||
IR_sp_func_num := bv_to_natural(IR_sp_func);
|
||||
IR_fp_func_num := bv_to_natural(IR_fp_func);
|
||||
rs1 := bv_to_natural(IR_rs1);
|
||||
rs2 := bv_to_natural(IR_rs2);
|
||||
Itype_rd := bv_to_natural(IR_Itype_rd);
|
||||
Rtype_rd := bv_to_natural(IR_Rtype_rd);
|
||||
--
|
||||
-------------------------------------------------------------------------
|
||||
-- instrumentation: increment counter for decoded instruction
|
||||
-------------------------------------------------------------------------
|
||||
--
|
||||
op_count(IR_opcode_num) := op_count(IR_opcode_num) + 1;
|
||||
if IR_opcode = op_special then
|
||||
sp_func_count(IR_sp_func_num) := sp_func_count(IR_sp_func_num) + 1;
|
||||
elsif IR_opcode = op_fparith then
|
||||
fp_func_count(IR_fp_func_num) := fp_func_count(IR_fp_func_num) + 1;
|
||||
end if;
|
||||
instr_count := instr_count + 1;
|
||||
--
|
||||
-------------------------------------------------------------------------
|
||||
--
|
||||
-- exectute
|
||||
--
|
||||
if debug then
|
||||
write(L, tag);
|
||||
write(L, string'(": executing instruction..."));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
--
|
||||
case IR_opcode is
|
||||
when op_special =>
|
||||
case IR_sp_func is
|
||||
WHEN sp_func_nop =>
|
||||
null;
|
||||
when sp_func_sll =>
|
||||
reg(Rtype_rd) := bv_sll(reg(rs1), bv_to_natural(reg(rs2)(27 to 31)));
|
||||
when sp_func_srl =>
|
||||
reg(Rtype_rd) := bv_srl(reg(rs1), bv_to_natural(reg(rs2)(27 to 31)));
|
||||
when sp_func_sra =>
|
||||
reg(Rtype_rd) := bv_sra(reg(rs1), bv_to_natural(reg(rs2)(27 to 31)));
|
||||
when sp_func_sequ =>
|
||||
if reg(rs1) = reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sneu =>
|
||||
if reg(rs1) /= reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sltu =>
|
||||
if reg(rs1) < reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sgtu =>
|
||||
if reg(rs1) > reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sleu =>
|
||||
if reg(rs1) <= reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sgeu =>
|
||||
if reg(rs1) >= reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_add =>
|
||||
bv_add(reg(rs1), reg(rs2), reg(Rtype_rd), overflow);
|
||||
when sp_func_addu =>
|
||||
bv_addu(reg(rs1), reg(rs2), reg(Rtype_rd), overflow);
|
||||
when sp_func_sub =>
|
||||
bv_sub(reg(rs1), reg(rs2), reg(Rtype_rd), overflow);
|
||||
when sp_func_subu =>
|
||||
bv_subu(reg(rs1), reg(rs2), reg(Rtype_rd), overflow);
|
||||
when sp_func_and =>
|
||||
reg(Rtype_rd) := reg(rs1) and reg(rs2);
|
||||
when sp_func_or =>
|
||||
reg(Rtype_rd) := reg(rs1) or reg(rs2);
|
||||
when sp_func_xor =>
|
||||
reg(Rtype_rd) := reg(rs1) xor reg(rs2);
|
||||
when sp_func_seq =>
|
||||
if reg(rs1) = reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sne =>
|
||||
if reg(rs1) /= reg(rs2) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_slt =>
|
||||
if bv_lt(reg(rs1), reg(rs2)) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sgt =>
|
||||
if bv_gt(reg(rs1), reg(rs2)) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sle =>
|
||||
if bv_le(reg(rs1), reg(rs2)) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_sge =>
|
||||
if bv_ge(reg(rs1), reg(rs2)) then
|
||||
reg(Rtype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Rtype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when sp_func_movi2s =>
|
||||
assert false
|
||||
report "MOVI2S instruction not implemented" severity warning;
|
||||
when sp_func_movs2i =>
|
||||
assert false
|
||||
report "MOVS2I instruction not implemented" severity warning;
|
||||
when sp_func_movf =>
|
||||
assert false
|
||||
report "MOVF instruction not implemented" severity warning;
|
||||
when sp_func_movd =>
|
||||
assert false
|
||||
report "MOVD instruction not implemented" severity warning;
|
||||
when sp_func_movfp2i =>
|
||||
reg(Rtype_rd) := fp_reg(rs1);
|
||||
when sp_func_movi2fp =>
|
||||
fp_reg(Rtype_rd) := reg(rs1);
|
||||
when others =>
|
||||
assert false
|
||||
report "undefined special instruction function" severity error;
|
||||
end case;
|
||||
when op_fparith =>
|
||||
case IR_fp_func is
|
||||
when fp_func_mult =>
|
||||
bv_mult(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), overflow);
|
||||
when fp_func_multu =>
|
||||
bv_multu(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), overflow);
|
||||
when fp_func_div =>
|
||||
bv_div(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), div_by_zero, overflow);
|
||||
when fp_func_divu =>
|
||||
bv_divu(fp_reg(rs1), fp_reg(rs2), fp_reg(Rtype_rd), div_by_zero);
|
||||
when fp_func_addf | fp_func_subf | fp_func_multf | fp_func_divf |
|
||||
fp_func_addd | fp_func_subd | fp_func_multd | fp_func_divd |
|
||||
fp_func_cvtf2d | fp_func_cvtf2i | fp_func_cvtd2f |
|
||||
fp_func_cvtd2i | fp_func_cvti2f | fp_func_cvti2d |
|
||||
fp_func_eqf | fp_func_nef | fp_func_ltf | fp_func_gtf |
|
||||
fp_func_lef | fp_func_gef | fp_func_eqd | fp_func_ned |
|
||||
fp_func_ltd | fp_func_gtd | fp_func_led | fp_func_ged =>
|
||||
assert false
|
||||
report "floating point instructions not implemented" severity warning;
|
||||
when others =>
|
||||
assert false
|
||||
report "undefined floating point instruction function" severity error;
|
||||
end case;
|
||||
when op_j =>
|
||||
bv_add(PC, bv_sext(IR_immed26, 32), PC, overflow);
|
||||
when op_jal =>
|
||||
reg(link_reg) := PC;
|
||||
bv_add(PC, bv_sext(IR_immed26, 32), PC, overflow);
|
||||
when op_beqz =>
|
||||
if reg(rs1) = X"0000_0000" then
|
||||
bv_add(PC, bv_sext(IR_immed16, 32), PC, overflow);
|
||||
end if;
|
||||
when op_bnez =>
|
||||
if reg(rs1) /= X"0000_0000" then
|
||||
bv_add(PC, bv_sext(IR_immed16, 32), PC, overflow);
|
||||
end if;
|
||||
when op_bfpt =>
|
||||
assert false
|
||||
report "BFPT instruction not implemented" severity warning;
|
||||
when op_bfpf =>
|
||||
assert false
|
||||
report "BFPF instruction not implemented" severity warning;
|
||||
when op_addi =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), reg(Itype_rd), overflow);
|
||||
when op_addui =>
|
||||
bv_addu(reg(rs1), bv_zext(IR_immed16, 32), reg(Itype_rd), overflow);
|
||||
when op_subi =>
|
||||
bv_sub(reg(rs1), bv_sext(IR_immed16, 32), reg(Itype_rd), overflow);
|
||||
when op_subui =>
|
||||
bv_subu(reg(rs1), bv_zext(IR_immed16, 32), reg(Itype_rd), overflow);
|
||||
when op_slli =>
|
||||
reg(Itype_rd) := bv_sll(reg(rs1), bv_to_natural(IR_immed16(11 to 15)));
|
||||
when op_srli =>
|
||||
reg(Itype_rd) := bv_srl(reg(rs1), bv_to_natural(IR_immed16(11 to 15)));
|
||||
when op_srai =>
|
||||
reg(Itype_rd) := bv_sra(reg(rs1), bv_to_natural(IR_immed16(11 to 15)));
|
||||
when op_andi =>
|
||||
reg(Itype_rd) := reg(rs1) and bv_zext(IR_immed16, 32);
|
||||
when op_ori =>
|
||||
reg(Itype_rd) := reg(rs1) or bv_zext(IR_immed16, 32);
|
||||
when op_xori =>
|
||||
reg(Itype_rd) := reg(rs1) xor bv_zext(IR_immed16, 32);
|
||||
when op_lhi =>
|
||||
reg(Itype_rd) := IR_immed16 & X"0000";
|
||||
when op_rfe =>
|
||||
assert false
|
||||
report "RFE instruction not implemented" severity warning;
|
||||
when op_trap =>
|
||||
assert false
|
||||
report "TRAP instruction encountered, execution halted"
|
||||
severity note;
|
||||
halt <= '1' after Tpd_clk_out;
|
||||
---------------------------------------------------------------------
|
||||
-- instrumentation: dump counters
|
||||
---------------------------------------------------------------------
|
||||
instrumentation_dump;
|
||||
---------------------------------------------------------------------
|
||||
wait until reset = '1';
|
||||
exit;
|
||||
when op_jr =>
|
||||
PC := reg(rs1);
|
||||
when op_jalr =>
|
||||
reg(link_reg) := PC;
|
||||
PC := reg(rs1);
|
||||
when op_seqi =>
|
||||
if reg(rs1) = bv_sext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_snei =>
|
||||
if reg(rs1) /= bv_sext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_slti =>
|
||||
if bv_lt(reg(rs1), bv_sext(IR_immed16, 32)) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_sgti =>
|
||||
if bv_gt(reg(rs1), bv_sext(IR_immed16, 32)) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_slei =>
|
||||
if bv_le(reg(rs1), bv_sext(IR_immed16, 32)) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_sgei =>
|
||||
if bv_ge(reg(rs1), bv_sext(IR_immed16, 32)) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_lb =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
bus_read(mem_addr, width_byte, false, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
case ls_2_addr_bits'(mem_addr(1 downto 0)) is
|
||||
when B"00" =>
|
||||
reg(Itype_rd) := bv_sext(mem_data(0 to 7), 32);
|
||||
when B"01" =>
|
||||
reg(Itype_rd) := bv_sext(mem_data(8 to 15), 32);
|
||||
when B"10" =>
|
||||
reg(Itype_rd) := bv_sext(mem_data(16 to 23), 32);
|
||||
when B"11" =>
|
||||
reg(Itype_rd) := bv_sext(mem_data(24 to 31), 32);
|
||||
end case;
|
||||
when op_lh =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
bus_read(mem_addr, width_halfword, false, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
if mem_addr(1) = '0' then
|
||||
reg(Itype_rd) := bv_sext(mem_data(0 to 15), 32);
|
||||
else
|
||||
reg(Itype_rd) := bv_sext(mem_data(16 to 31), 32);
|
||||
end if;
|
||||
when op_lw =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
bus_read(mem_addr, width_word, false, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
reg(Itype_rd) := mem_data;
|
||||
when op_lbu =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
bus_read(mem_addr, width_byte, false, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
case ls_2_addr_bits'(mem_addr(1 downto 0)) is
|
||||
when B"00" =>
|
||||
reg(Itype_rd) := bv_zext(mem_data(0 to 7), 32);
|
||||
when B"01" =>
|
||||
reg(Itype_rd) := bv_zext(mem_data(8 to 15), 32);
|
||||
when B"10" =>
|
||||
reg(Itype_rd) := bv_zext(mem_data(16 to 23), 32);
|
||||
when B"11" =>
|
||||
reg(Itype_rd) := bv_zext(mem_data(24 to 31), 32);
|
||||
end case;
|
||||
when op_lhu =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
bus_read(mem_addr, width_halfword, false, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
if mem_addr(1) = '0' then
|
||||
reg(Itype_rd) := bv_zext(mem_data(0 to 15), 32);
|
||||
else
|
||||
reg(Itype_rd) := bv_zext(mem_data(16 to 31), 32);
|
||||
end if;
|
||||
when op_lf =>
|
||||
assert false
|
||||
report "LF instruction not implemented" severity warning;
|
||||
when op_ld =>
|
||||
assert false
|
||||
report "LD instruction not implemented" severity warning;
|
||||
when op_sb =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
mem_data := X"0000_0000";
|
||||
case ls_2_addr_bits'(mem_addr(1 downto 0)) is
|
||||
when B"00" =>
|
||||
mem_data(0 to 7) := reg(Itype_rd)(0 to 7);
|
||||
when B"01" =>
|
||||
mem_data(8 to 15) := reg(Itype_rd)(0 to 7);
|
||||
when B"10" =>
|
||||
mem_data(16 to 23) := reg(Itype_rd)(0 to 7);
|
||||
when B"11" =>
|
||||
mem_data(24 to 31) := reg(Itype_rd)(0 to 7);
|
||||
end case;
|
||||
write(mem_addr, width_halfword, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
when op_sh =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
mem_data := X"0000_0000";
|
||||
if mem_addr(1) = '0' then
|
||||
mem_data(0 to 15) := reg(Itype_rd)(0 to 15);
|
||||
else
|
||||
mem_data(16 to 31) := reg(Itype_rd)(0 to 15);
|
||||
end if;
|
||||
write(mem_addr, width_halfword, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
when op_sw =>
|
||||
bv_add(reg(rs1), bv_sext(IR_immed16, 32), mem_addr, overflow);
|
||||
mem_data := reg(Itype_rd);
|
||||
write(mem_addr, width_word, mem_data,
|
||||
phi1, phi2, reset, a, d, width, write_enable, mem_enable, ifetch, ready,
|
||||
Tpd_clk_out);
|
||||
exit when reset = '1';
|
||||
when op_sf =>
|
||||
assert false
|
||||
report "SF instruction not implemented" severity warning;
|
||||
when op_sd =>
|
||||
assert false
|
||||
report "SD instruction not implemented" severity warning;
|
||||
when op_sequi =>
|
||||
if reg(rs1) = bv_zext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_sneui =>
|
||||
if reg(rs1) /= bv_zext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_sltui =>
|
||||
if reg(rs1) < bv_zext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_sgtui =>
|
||||
if reg(rs1) > bv_zext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_sleui =>
|
||||
if reg(rs1) <= bv_zext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when op_sgeui =>
|
||||
if reg(rs1) >= bv_zext(IR_immed16, 32) then
|
||||
reg(Itype_rd) := X"0000_0001";
|
||||
else
|
||||
reg(Itype_rd) := X"0000_0000";
|
||||
end if;
|
||||
when others =>
|
||||
assert false
|
||||
report "undefined instruction" severity error;
|
||||
end case;
|
||||
--
|
||||
-- fix up R0 in case it was overwritten
|
||||
--
|
||||
reg(0) := X"0000_0000";
|
||||
--
|
||||
if debug then
|
||||
write(L, tag);
|
||||
write(L, string'(": end of execution"));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
if instr_count mod 100 = 0 then
|
||||
write(L, tag);
|
||||
write(L, string'(": executed "));
|
||||
write(L, instr_count);
|
||||
write(L, string'(" instructions"));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
--
|
||||
end loop;
|
||||
--
|
||||
-- loop is only exited when reset active: wait until it goes inactive
|
||||
--
|
||||
assert reset = '1'
|
||||
report "reset code reached with reset = '0'" severity error;
|
||||
wait until phi2 = '0' and reset = '0';
|
||||
--
|
||||
-- process interpreter now starts again from beginning
|
||||
--
|
||||
end process interpreter;
|
||||
|
||||
end instrumented;
|
||||
@@ -0,0 +1,286 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx-rtl.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 19:54:44 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Register transfer level architecture of DLX processor.
|
||||
--
|
||||
|
||||
|
||||
use std.textio.all,
|
||||
work.images.image_hex,
|
||||
work.bv_arithmetic.all,
|
||||
work.dlx_instr.all,
|
||||
work.alu_types.all;
|
||||
|
||||
|
||||
architecture rtl of dlx is
|
||||
|
||||
component alu
|
||||
port (s1 : in dlx_word;
|
||||
s2 : in dlx_word;
|
||||
result : out dlx_word;
|
||||
latch_en : in bit;
|
||||
func : in alu_func;
|
||||
zero, negative, overflow : out bit);
|
||||
end component;
|
||||
|
||||
component reg_file
|
||||
port (a1 : in dlx_reg_addr; -- port1 address
|
||||
q1 : out dlx_word; -- port1 read data
|
||||
a2 : in dlx_reg_addr; -- port2 address
|
||||
q2 : out dlx_word; -- port2 read data
|
||||
a3 : in dlx_reg_addr; -- port3 address
|
||||
d3 : in dlx_word; -- port3 write data
|
||||
write_en : in bit); -- port3 write enable
|
||||
end component;
|
||||
|
||||
component latch
|
||||
port (d : in dlx_word;
|
||||
q : out dlx_word;
|
||||
latch_en : in bit);
|
||||
end component;
|
||||
|
||||
component reg_1_out
|
||||
port (d : in dlx_word;
|
||||
q : out dlx_word_bus bus;
|
||||
latch_en : in bit;
|
||||
out_en : in bit);
|
||||
end component;
|
||||
|
||||
component reg_2_out
|
||||
port (d : in dlx_word;
|
||||
q1, q2 : out dlx_word_bus bus;
|
||||
latch_en : in bit;
|
||||
out_en1, out_en2 : in bit);
|
||||
end component;
|
||||
|
||||
component reg_3_out
|
||||
port (d : in dlx_word;
|
||||
q1, q2, q3 : out dlx_word_bus bus;
|
||||
latch_en : in bit;
|
||||
out_en1, out_en2, out_en3 : in bit);
|
||||
end component;
|
||||
|
||||
component reg_2_1_out
|
||||
port (d : in dlx_word;
|
||||
q1, q2 : out dlx_word_bus bus;
|
||||
q3 : out dlx_word;
|
||||
latch_en : in bit;
|
||||
out_en1, out_en2 : in bit);
|
||||
end component;
|
||||
|
||||
component mux2
|
||||
port (i0, i1 : in dlx_word;
|
||||
y : out dlx_word;
|
||||
sel : in bit);
|
||||
end component;
|
||||
|
||||
component ir
|
||||
port (d : in dlx_word; -- instruction input from memory
|
||||
immed_q1, immed_q2 : out dlx_word_bus bus;
|
||||
ir_out : out dlx_word; -- instruction output to control
|
||||
latch_en : in bit;
|
||||
immed_sel1, immed_sel2 : in immed_size; -- select 16-bit or 26-bit immed
|
||||
immed_unsigned1, immed_unsigned2 : in bit; -- extend immed unsigned/signed
|
||||
immed_en1, immed_en2 : in bit); -- enable immed const outputs
|
||||
end component;
|
||||
|
||||
component controller
|
||||
port (phi1, phi2 : in bit;
|
||||
reset : in bit;
|
||||
halt : out bit;
|
||||
width : out mem_width;
|
||||
write_enable : out bit;
|
||||
mem_enable : out bit;
|
||||
ifetch : out bit;
|
||||
ready : in bit;
|
||||
alu_latch_en : out bit;
|
||||
alu_function : out alu_func;
|
||||
alu_zero, alu_negative, alu_overflow : in bit;
|
||||
reg_s1_addr, reg_s2_addr, reg_dest_addr : out dlx_reg_addr;
|
||||
reg_write : out bit;
|
||||
c_latch_en : out bit;
|
||||
a_latch_en, a_out_en : out bit;
|
||||
b_latch_en, b_out_en : out bit;
|
||||
temp_latch_en, temp_out_en1, temp_out_en2 : out bit;
|
||||
iar_latch_en, iar_out_en1, iar_out_en2 : out bit;
|
||||
pc_latch_en, pc_out_en1, pc_out_en2 : out bit;
|
||||
mar_latch_en, mar_out_en1, mar_out_en2 : out bit;
|
||||
mem_addr_mux_sel : out bit;
|
||||
mdr_latch_en, mdr_out_en1, mdr_out_en2, mdr_out_en3 : out bit;
|
||||
mdr_mux_sel : out bit;
|
||||
ir_latch_en : out bit;
|
||||
ir_immed_sel1, ir_immed_sel2 : out immed_size;
|
||||
ir_immed_unsigned1, ir_immed_unsigned2 : out bit;
|
||||
ir_immed_en1, ir_immed_en2 : out bit;
|
||||
current_instruction : in dlx_word;
|
||||
const1, const2 : out dlx_word_bus bus);
|
||||
end component;
|
||||
|
||||
signal s1_bus, s2_bus : dlx_word_bus;
|
||||
signal dest_bus : dlx_word;
|
||||
signal alu_latch_en : bit;
|
||||
signal alu_function : alu_func;
|
||||
signal alu_zero, alu_negative, alu_overflow : bit;
|
||||
signal reg_s1_addr, reg_s2_addr, reg_dest_addr : dlx_reg_addr;
|
||||
signal reg_file_out1, reg_file_out2, reg_file_in : dlx_word;
|
||||
signal reg_write : bit;
|
||||
signal a_out_en, a_latch_en : bit;
|
||||
signal b_out_en, b_latch_en : bit;
|
||||
signal c_latch_en : bit;
|
||||
signal temp_out_en1, temp_out_en2, temp_latch_en : bit;
|
||||
signal iar_out_en1, iar_out_en2, iar_latch_en : bit;
|
||||
signal pc_out_en1, pc_out_en2, pc_latch_en : bit;
|
||||
signal pc_to_mem : dlx_word;
|
||||
signal mar_out_en1, mar_out_en2, mar_latch_en : bit;
|
||||
signal mar_to_mem : dlx_word;
|
||||
signal mem_addr_mux_sel : bit;
|
||||
signal mdr_out_en1, mdr_out_en2, mdr_out_en3, mdr_latch_en : bit;
|
||||
signal mdr_in : dlx_word;
|
||||
signal mdr_mux_sel : bit;
|
||||
signal current_instruction : dlx_word;
|
||||
signal ir_latch_en : bit;
|
||||
signal ir_immed_sel1, ir_immed_sel2 : immed_size;
|
||||
signal ir_immed_unsigned1, ir_immed_unsigned2 : bit;
|
||||
signal ir_immed_en1, ir_immed_en2 : bit;
|
||||
|
||||
begin
|
||||
|
||||
the_alu : alu
|
||||
port map (s1 => s1_bus, s2 => s2_bus, result => dest_bus,
|
||||
latch_en => alu_latch_en, func => alu_function,
|
||||
zero => alu_zero, negative => alu_negative, overflow => alu_overflow);
|
||||
|
||||
the_reg_file : reg_file
|
||||
port map (a1 => reg_s1_addr, q1 => reg_file_out1,
|
||||
a2 => reg_s2_addr, q2 => reg_file_out2,
|
||||
a3 => reg_dest_addr, d3 => reg_file_in,
|
||||
write_en => reg_write);
|
||||
|
||||
c_reg : latch
|
||||
port map (d => dest_bus, q => reg_file_in, latch_en => c_latch_en);
|
||||
|
||||
a_reg : reg_1_out
|
||||
port map (d => reg_file_out1, q => s1_bus,
|
||||
latch_en => a_latch_en, out_en => a_out_en);
|
||||
|
||||
b_reg : reg_1_out
|
||||
port map (d => reg_file_out2, q => s2_bus,
|
||||
latch_en => b_latch_en, out_en => b_out_en);
|
||||
|
||||
temp_reg : reg_2_out
|
||||
port map (d => dest_bus, q1 => s1_bus, q2 => s2_bus,
|
||||
latch_en => temp_latch_en,
|
||||
out_en1 => temp_out_en1, out_en2 => temp_out_en2);
|
||||
|
||||
iar_reg : reg_2_out
|
||||
port map (d => dest_bus, q1 => s1_bus, q2 => s2_bus,
|
||||
latch_en => iar_latch_en,
|
||||
out_en1 => iar_out_en1, out_en2 => iar_out_en2);
|
||||
|
||||
pc_reg : reg_2_1_out
|
||||
port map (d => dest_bus, q1 => s1_bus, q2 => s2_bus, q3 => pc_to_mem,
|
||||
latch_en => pc_latch_en,
|
||||
out_en1 => pc_out_en1, out_en2 => pc_out_en2);
|
||||
|
||||
mar_reg : reg_2_1_out
|
||||
port map (d => dest_bus, q1 => s1_bus, q2 => s2_bus, q3 => mar_to_mem,
|
||||
latch_en => mar_latch_en,
|
||||
out_en1 => mar_out_en1, out_en2 => mar_out_en2);
|
||||
|
||||
mem_addr_mux : mux2
|
||||
port map (i0 => pc_to_mem, i1 => mar_to_mem, y => a,
|
||||
sel => mem_addr_mux_sel);
|
||||
|
||||
mdr_reg : reg_3_out
|
||||
port map (d => mdr_in, q1 => s1_bus, q2 => s2_bus, q3 => d,
|
||||
latch_en => mdr_latch_en,
|
||||
out_en1 => mdr_out_en1, out_en2 => mdr_out_en2,
|
||||
out_en3 => mdr_out_en3);
|
||||
|
||||
mdr_mux : mux2
|
||||
port map (i0 => dest_bus, i1 => d, y => mdr_in,
|
||||
sel => mdr_mux_sel);
|
||||
|
||||
instr_reg : ir
|
||||
port map (d => d, immed_q1 => s1_bus, immed_q2 => s2_bus,
|
||||
ir_out => current_instruction,
|
||||
latch_en => ir_latch_en,
|
||||
immed_sel1 => ir_immed_sel1, immed_sel2 => ir_immed_sel2,
|
||||
immed_unsigned1 => ir_immed_unsigned1,
|
||||
immed_unsigned2 => ir_immed_unsigned2,
|
||||
immed_en1 => ir_immed_en1, immed_en2 => ir_immed_en2);
|
||||
|
||||
the_controller : controller
|
||||
port map (phi1, phi2, reset, halt,
|
||||
width, write_enable, mem_enable, ifetch, ready,
|
||||
alu_latch_en, alu_function, alu_zero, alu_negative, alu_overflow,
|
||||
reg_s1_addr, reg_s2_addr, reg_dest_addr, reg_write,
|
||||
c_latch_en, a_latch_en, a_out_en, b_latch_en, b_out_en,
|
||||
temp_latch_en, temp_out_en1, temp_out_en2,
|
||||
iar_latch_en, iar_out_en1, iar_out_en2,
|
||||
pc_latch_en, pc_out_en1, pc_out_en2,
|
||||
mar_latch_en, mar_out_en1, mar_out_en2, mem_addr_mux_sel,
|
||||
mdr_latch_en, mdr_out_en1, mdr_out_en2,
|
||||
mdr_out_en3, mdr_mux_sel,
|
||||
ir_latch_en, ir_immed_sel1, ir_immed_sel2,
|
||||
ir_immed_unsigned1, ir_immed_unsigned2, ir_immed_en1, ir_immed_en2,
|
||||
current_instruction, s1_bus, s2_bus);
|
||||
|
||||
debug_s1 : if debug generate
|
||||
s1_monitor : process (s1_bus)
|
||||
variable L : line;
|
||||
begin
|
||||
write(L, tag);
|
||||
write(L, string'(" s1_monitor: "));
|
||||
write(L, image_hex(s1_bus));
|
||||
writeline(output, L);
|
||||
end process s1_monitor;
|
||||
end generate;
|
||||
|
||||
debug_s2 : if debug generate
|
||||
s2_monitor : process (s2_bus)
|
||||
variable L : line;
|
||||
begin
|
||||
write(L, tag);
|
||||
write(L, string'(" s2_monitor: "));
|
||||
write(L, image_hex(s2_bus));
|
||||
writeline(output, L);
|
||||
end process s2_monitor;
|
||||
end generate;
|
||||
|
||||
debug_dest : if debug generate
|
||||
dest_monitor : process (dest_bus)
|
||||
variable L : line;
|
||||
begin
|
||||
write(L, tag);
|
||||
write(L, string'(" dest_monitor: "));
|
||||
write(L, image_hex(dest_bus));
|
||||
writeline(output, L);
|
||||
end process dest_monitor;
|
||||
end generate;
|
||||
|
||||
end rtl;
|
||||
@@ -0,0 +1,50 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 22:37:14 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity specification for DLX processor
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_types.all,
|
||||
work.mem_types.all;
|
||||
|
||||
entity dlx is
|
||||
generic (Tpd_clk_out : Time; -- clock to output propagation delay
|
||||
debug : boolean := false; -- controls debug trace writes
|
||||
tag : string := "";
|
||||
origin_x, origin_y : real := 0.0);
|
||||
port (phi1, phi2 : in bit; -- 2-phase non-overlapping clocks
|
||||
reset : in bit; -- synchronous reset input
|
||||
a : out dlx_address; -- address bus output
|
||||
d : inout dlx_word_bus bus; -- bidirectional data bus
|
||||
halt : out bit; -- halt indicator
|
||||
width : out mem_width; -- byte/haldword/word indicator
|
||||
write_enable : out bit; -- selects read or write cycle
|
||||
mem_enable : out bit; -- starts memory cycle
|
||||
ifetch : out bit; -- indicates instruction fetch
|
||||
ready : in bit); -- status from memory system
|
||||
end dlx;
|
||||
@@ -0,0 +1,171 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx_bus_monitor-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 22:36:40 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture of DLX bus monitor
|
||||
--
|
||||
|
||||
|
||||
use std.textio.all,
|
||||
work.dlx_instr.all,
|
||||
work.images.image_hex;
|
||||
|
||||
|
||||
architecture behaviour of dlx_bus_monitor is
|
||||
|
||||
begin
|
||||
|
||||
monitor : if enable generate
|
||||
|
||||
enabled_monitor : process
|
||||
|
||||
variable write_command, instr_fetch : boolean;
|
||||
variable L : line;
|
||||
|
||||
begin
|
||||
monitor_loop : loop
|
||||
--
|
||||
-- wait for a command, valid on leading edge of phi2
|
||||
--
|
||||
wait until phi2 = '1' and mem_enable = '1';
|
||||
--
|
||||
-- capture the command information
|
||||
--
|
||||
write_command := write_enable = '1';
|
||||
instr_fetch := ifetch = '1';
|
||||
write(L, tag);
|
||||
write(L, string'(": "));
|
||||
if write_command then
|
||||
write(L, string'("D-write to "));
|
||||
elsif instr_fetch then
|
||||
write(L, string'("I-fetch from "));
|
||||
else
|
||||
write(L, string'("D-read from "));
|
||||
end if;
|
||||
write(L, image_hex(a));
|
||||
if verbose then
|
||||
case width is
|
||||
when width_word =>
|
||||
write(L, string'(", word"));
|
||||
when width_halfword =>
|
||||
write(L, string'(", halfword"));
|
||||
when width_byte =>
|
||||
write(L, string'(", byte"));
|
||||
end case;
|
||||
if burst = '1' then
|
||||
write(L, string'(", burst "));
|
||||
else
|
||||
write(L, string'(", single "));
|
||||
end if;
|
||||
writeline(output, L);
|
||||
else
|
||||
if not instr_fetch then
|
||||
write(L, string'(", data"));
|
||||
else
|
||||
writeline(output, L);
|
||||
end if;
|
||||
end if;
|
||||
--
|
||||
burst_loop : loop
|
||||
if write_command then
|
||||
if verbose then
|
||||
write(L, tag);
|
||||
write(L, string'(": Write data "));
|
||||
write(L, image_hex(d));
|
||||
writeline(output, L);
|
||||
else
|
||||
write(L, ' ');
|
||||
write(L, image_hex(d));
|
||||
end if;
|
||||
end if;
|
||||
-- wait for the response from memory
|
||||
loop
|
||||
wait until phi2 = '0';
|
||||
if reset = '1' then
|
||||
exit monitor_loop;
|
||||
end if;
|
||||
exit when ready = '1';
|
||||
end loop;
|
||||
if write_command then
|
||||
if verbose then
|
||||
write(L, tag);
|
||||
write(L, string'(": Ready"));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
elsif instr_fetch then
|
||||
if verbose then
|
||||
write(L, tag);
|
||||
write(L, string'(": Ready, instruction "));
|
||||
write(L, image_hex(d));
|
||||
write(L, string'(" [ "));
|
||||
write_instr(L, d);
|
||||
write(L, string'(" ]"));
|
||||
writeline(output, L);
|
||||
else -- brief instruction fetch
|
||||
write(L, tag);
|
||||
write(L, string'(": "));
|
||||
write(L, image_hex(d));
|
||||
write(L, string'(" [ "));
|
||||
write_instr(L, d);
|
||||
write(L, string'(" ]"));
|
||||
writeline(output, L);
|
||||
end if;
|
||||
else -- data fetch
|
||||
if verbose then
|
||||
write(L, tag);
|
||||
write(L, string'(": Ready, data "));
|
||||
write(L, image_hex(d));
|
||||
writeline(output, L);
|
||||
else -- brief data fetch
|
||||
write(L, ' ');
|
||||
write(L, image_hex(d));
|
||||
end if;
|
||||
end if;
|
||||
exit burst_loop when burst = '0';
|
||||
end loop burst_loop;
|
||||
--
|
||||
if not verbose and not instr_fetch then
|
||||
writeline(output, L);
|
||||
end if;
|
||||
end loop monitor_loop;
|
||||
--
|
||||
-- get here when reset is asserted
|
||||
--
|
||||
assert reset = '1'
|
||||
report "reset code reached with reset = '0'" severity error;
|
||||
write(L, string'("DLX_bus_monitor: Reset"));
|
||||
writeline(output, L);
|
||||
wait until phi2 = '0' and reset = '0';
|
||||
write(L, string'("DLX_bus_monitor: End Reset"));
|
||||
writeline(output, L);
|
||||
--
|
||||
-- process monitor now starts again from beginning
|
||||
--
|
||||
end process enabled_monitor;
|
||||
|
||||
end generate;
|
||||
|
||||
end behaviour;
|
||||
@@ -0,0 +1,50 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx_bus_monitor.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 22:35:51 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration of DLX bus monitor
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_types.all,
|
||||
work.mem_types.all;
|
||||
|
||||
entity dlx_bus_monitor is
|
||||
generic (enable : boolean := true; -- enable monitoring
|
||||
verbose : boolean := true; -- verbose vs brief info
|
||||
tag : string := "");
|
||||
port (phi1, phi2 : in bit; -- 2-phase non-overlapping clocks
|
||||
reset : in bit; -- synchronous reset
|
||||
a : in dlx_address; -- address bus
|
||||
d : in dlx_word; -- data bus
|
||||
halt : in bit; -- halt indicator
|
||||
width : in mem_width; -- byte/haldword/word indicator
|
||||
write_enable : in bit; -- selects read or write cycle
|
||||
burst : in bit := '0'; -- indicates more to come in burst
|
||||
mem_enable : in bit; -- starts memory cycle
|
||||
ifetch : in bit; -- indicates instruction fetch
|
||||
ready : in bit); -- status from memory system
|
||||
end dlx_bus_monitor;
|
||||
@@ -0,0 +1,258 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx_instr-body.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 22:35:21 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Package body for DLX instructions
|
||||
--
|
||||
|
||||
|
||||
use std.textio.all,
|
||||
work.bv_arithmetic.bv_to_natural,
|
||||
work.bv_arithmetic.bv_to_integer;
|
||||
|
||||
|
||||
package body dlx_instr is
|
||||
|
||||
constant opcode_names : opcode_name_array :=
|
||||
( "SPECIAL ", "FPARITH ", "J ", "JAL ",
|
||||
"BEQZ ", "BNEZ ", "BFPT ", "BFPF ",
|
||||
"ADDI ", "ADDUI ", "SUBI ", "SUBUI ",
|
||||
"ANDI ", "ORI ", "XORI ", "LHI ",
|
||||
"RFE ", "TRAP ", "JR ", "JALR ",
|
||||
"SLLI ", "UNDEF_15", "SRLI ", "SRAI ",
|
||||
"SEQI ", "SNEI ", "SLTI ", "SGTI ",
|
||||
"SLEI ", "SGEI ", "UNDEF_1E", "UNDEF_1F",
|
||||
"LB ", "LH ", "UNDEF_22", "LW ",
|
||||
"LBU ", "LHU ", "LF ", "LD ",
|
||||
"SB ", "SH ", "UNDEF_2A", "SW ",
|
||||
"UNDEF_2C", "UNDEF_2D", "SF ", "SD ",
|
||||
"SEQUI ", "SNEUI ", "SLTUI ", "SGTUI ",
|
||||
"SLEUI ", "SGEUI ", "UNDEF_36", "UNDEF_37",
|
||||
"UNDEF_38", "UNDEF_39", "UNDEF_3A", "UNDEF_3B",
|
||||
"UNDEF_3C", "UNDEF_3D", "UNDEF_3E", "UNDEF_3F" );
|
||||
|
||||
constant sp_func_names : sp_func_name_array :=
|
||||
( "NOP ", "UNDEF_01", "UNDEF_02", "UNDEF_03",
|
||||
"SLL ", "UNDEF_05", "SRL ", "SRA ",
|
||||
"UNDEF_08", "UNDEF_09", "UNDEF_0A", "UNDEF_0B",
|
||||
"UNDEF_0C", "UNDEF_0D", "UNDEF_0E", "UNDEF_0F",
|
||||
"SEQU ", "SNEU ", "SLTU ", "SGTU ",
|
||||
"SLEU ", "SGEU ", "UNDEF_16", "UNDEF_17",
|
||||
"UNDEF_18", "UNDEF_19", "UNDEF_1A", "UNDEF_1B",
|
||||
"UNDEF_1C", "UNDEF_1D", "UNDEF_1E", "UNDEF_1F",
|
||||
"ADD ", "ADDU ", "SUB ", "SUBU ",
|
||||
"AND ", "OR ", "XOR ", "UNDEF_27",
|
||||
"SEQ ", "SNE ", "SLT ", "SGT ",
|
||||
"SLE ", "SGE ", "UNDEF_2E", "UNDEF_2F",
|
||||
"MOVI2S ", "MOVS2I ", "MOVF ", "MOVD ",
|
||||
"MOVFP2I ", "MOVI2FP ", "UNDEF_36", "UNDEF_37",
|
||||
"UNDEF_38", "UNDEF_39", "UNDEF_3A", "UNDEF_3B",
|
||||
"UNDEF_3C", "UNDEF_3D", "UNDEF_3E", "UNDEF_3F" );
|
||||
|
||||
constant fp_func_names : fp_func_name_array :=
|
||||
( "ADDF ", "SUBF ", "MULTF ", "DIVF ",
|
||||
"ADDD ", "SUBD ", "MULTD ", "DIVD ",
|
||||
"CVTF2D ", "CVTF2I ", "CVTD2F ", "CVTD2I ",
|
||||
"CVTI2F ", "CVTI2D ", "MULT ", "DIV ",
|
||||
"EQF ", "NEF ", "LTF ", "GTF ",
|
||||
"LEF ", "GEF ", "MULTU ", "DIVU ",
|
||||
"EQD ", "NED ", "LTD ", "GTD ",
|
||||
"LED ", "GED ", "UNDEF_1E", "UNDEF_1F" );
|
||||
|
||||
|
||||
procedure write_reg (L : inout line; reg : reg_index) is
|
||||
|
||||
begin
|
||||
write(L, 'R');
|
||||
write(L, reg);
|
||||
end write_reg;
|
||||
|
||||
|
||||
procedure write_freg (L : inout line; freg : reg_index) is
|
||||
|
||||
begin
|
||||
write(L, 'F');
|
||||
write(L, freg);
|
||||
end write_freg;
|
||||
|
||||
|
||||
procedure write_special_reg (L : inout line; reg : reg_index) is
|
||||
|
||||
begin
|
||||
case reg is
|
||||
when 0 =>
|
||||
write(L, string'("IAR"));
|
||||
WHEN 1 =>
|
||||
write(L, string'("FSR"));
|
||||
when others =>
|
||||
write(L, string'("SR"));
|
||||
write(L, reg);
|
||||
end case;
|
||||
end write_special_reg;
|
||||
|
||||
|
||||
procedure write_instr (L : inout line; instr : in dlx_word) is
|
||||
|
||||
alias instr_opcode : dlx_opcode is instr(0 to 5);
|
||||
alias instr_sp_func : dlx_sp_func is instr(26 to 31);
|
||||
alias instr_fp_func : dlx_fp_func is instr(27 to 31);
|
||||
alias instr_rs1 : dlx_reg_addr is instr(6 to 10);
|
||||
alias instr_rs2 : dlx_reg_addr is instr(11 to 15);
|
||||
alias instr_Itype_rd : dlx_reg_addr is instr(11 to 15);
|
||||
alias instr_Rtype_rd : dlx_reg_addr is instr(16 to 20);
|
||||
alias instr_immed16 : dlx_immed16 is instr(16 to 31);
|
||||
alias instr_immed26 : dlx_immed26 is instr(6 to 31);
|
||||
|
||||
variable instr_opcode_num : dlx_opcode_num;
|
||||
variable instr_sp_func_num : dlx_sp_func_num;
|
||||
variable instr_fp_func_num : dlx_fp_func_num;
|
||||
variable rs1 : reg_index;
|
||||
variable rs2 : reg_index;
|
||||
variable Itype_rd : reg_index;
|
||||
variable Rtype_rd : reg_index;
|
||||
|
||||
begin
|
||||
instr_opcode_num := bv_to_natural(instr_opcode);
|
||||
instr_sp_func_num := bv_to_natural(instr_sp_func);
|
||||
instr_fp_func_num := bv_to_natural(instr_fp_func);
|
||||
rs1 := bv_to_natural(instr_rs1);
|
||||
rs2 := bv_to_natural(instr_rs2);
|
||||
Itype_rd := bv_to_natural(instr_Itype_rd);
|
||||
Rtype_rd := bv_to_natural(instr_Rtype_rd);
|
||||
--
|
||||
if (instr_opcode /= op_special) and (instr_opcode /= op_fparith) then
|
||||
write(L, opcode_names(instr_opcode_num));
|
||||
write(L, ' ');
|
||||
end if;
|
||||
case instr_opcode is
|
||||
when op_special =>
|
||||
write(L, sp_func_names(instr_sp_func_num));
|
||||
write(L, ' ');
|
||||
case instr_sp_func is
|
||||
when sp_func_nop =>
|
||||
null;
|
||||
when sp_func_sll | sp_func_srl | sp_func_sra |
|
||||
sp_func_sequ | sp_func_sneu | sp_func_sltu |
|
||||
sp_func_sgtu | sp_func_sleu | sp_func_sgeu |
|
||||
sp_func_add | sp_func_addu | sp_func_sub | sp_func_subu |
|
||||
sp_func_and | sp_func_or | sp_func_xor |
|
||||
sp_func_seq | sp_func_sne | sp_func_slt |
|
||||
sp_func_sgt | sp_func_sle | sp_func_sge =>
|
||||
write_reg(L, Rtype_rd); write(L, string'(", "));
|
||||
write_reg(L, rs1); write(L, string'(", "));
|
||||
write_reg(L, rs2);
|
||||
when sp_func_movi2s =>
|
||||
write_special_reg(L, Rtype_rd); write(L, string'(", "));
|
||||
write_reg(L, rs1);
|
||||
when sp_func_movs2i =>
|
||||
write_reg(L, Rtype_rd); write(L, string'(", "));
|
||||
write_special_reg(L, rs1);
|
||||
when sp_func_movf | sp_func_movd =>
|
||||
write_freg(L, Rtype_rd); write(L, string'(", "));
|
||||
write_freg(L, rs1);
|
||||
when sp_func_movfp2i =>
|
||||
write_reg(L, Rtype_rd); write(L, string'(", "));
|
||||
write_freg(L, rs1);
|
||||
when sp_func_movi2fp =>
|
||||
write_freg(L, Rtype_rd); write(L, string'(", "));
|
||||
write_reg(L, rs1);
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
when op_fparith =>
|
||||
write(L, fp_func_names(instr_fp_func_num));
|
||||
write(L, ' ');
|
||||
case instr_fp_func is
|
||||
when fp_func_addf | fp_func_subf | fp_func_multf | fp_func_divf |
|
||||
fp_func_addd | fp_func_subd | fp_func_multd | fp_func_divd |
|
||||
fp_func_mult | fp_func_div | fp_func_multu | fp_func_divu =>
|
||||
write_freg(L, Rtype_rd); write(L, string'(", "));
|
||||
write_freg(L, rs1); write(L, string'(", "));
|
||||
write_freg(L, rs2);
|
||||
when fp_func_cvtf2d | fp_func_cvtd2f =>
|
||||
write_freg(L, Rtype_rd); write(L, string'(", "));
|
||||
write_freg(L, rs1);
|
||||
when fp_func_cvtf2i | fp_func_cvtd2i =>
|
||||
write_reg(L, Rtype_rd); write(L, string'(", "));
|
||||
write_freg(L, rs1);
|
||||
when fp_func_cvti2f | fp_func_cvti2d =>
|
||||
write_freg(L, Rtype_rd); write(L, string'(", "));
|
||||
write_reg(L, rs1);
|
||||
when fp_func_eqf | fp_func_nef | fp_func_ltf |
|
||||
fp_func_gtf | fp_func_lef | fp_func_gef |
|
||||
fp_func_eqd | fp_func_ned | fp_func_ltd |
|
||||
fp_func_gtd | fp_func_led | fp_func_ged =>
|
||||
write_freg(L, rs1); write(L, string'(", "));
|
||||
write_freg(L, rs2);
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
when op_j | op_jal =>
|
||||
write(L, bv_to_integer(instr_immed26));
|
||||
when op_beqz | op_bnez =>
|
||||
write_reg(L, rs1); write(L, string'(", "));
|
||||
write(L, bv_to_integer(instr_immed16));
|
||||
when op_bfpt | op_bfpf =>
|
||||
write(L, bv_to_integer(instr_immed16));
|
||||
when op_slli | op_srli | op_srai =>
|
||||
write_reg(L, Itype_rd); write(L, string'(", "));
|
||||
write_reg(L, rs1); write(L, string'(", "));
|
||||
write(L, bv_to_natural(instr_immed16(11 to 15)));
|
||||
when op_addi | op_subi |
|
||||
op_seqi | op_snei | op_slti | op_sgti | op_slei | op_sgei =>
|
||||
write_reg(L, Itype_rd); write(L, string'(", "));
|
||||
write_reg(L, rs1); write(L, string'(", "));
|
||||
write(L, bv_to_integer(instr_immed16));
|
||||
when op_addui | op_subui | op_andi | op_ori | op_xori |
|
||||
op_sequi | op_sneui | op_sltui | op_sgtui | op_sleui | op_sgeui =>
|
||||
write_reg(L, Itype_rd); write(L, string'(", "));
|
||||
write_reg(L, rs1); write(L, string'(", "));
|
||||
write(L, bv_to_natural(instr_immed16));
|
||||
when op_lhi =>
|
||||
write_reg(L, Itype_rd); write(L, string'(", "));
|
||||
write(L, bv_to_natural(instr_immed16));
|
||||
when op_rfe =>
|
||||
null;
|
||||
when op_trap =>
|
||||
write(L, bv_to_natural(instr_immed26));
|
||||
when op_jr | op_jalr =>
|
||||
write_reg(L, rs1);
|
||||
when op_lb | op_lh | op_lw |
|
||||
op_lbu | op_lhu | op_lf | op_ld =>
|
||||
write_reg(L, Itype_rd); write(L, string'(", "));
|
||||
write(L, bv_to_integer(instr_immed16)); write(L, '(');
|
||||
write_reg(L, rs1); write(L, ')');
|
||||
when op_sb | op_sh | op_sw | op_sf | op_sd =>
|
||||
write(L, bv_to_integer(instr_immed16));
|
||||
write(L, '('); write_reg(L, rs1); write(L, string'("), "));
|
||||
write_reg(L, Itype_rd);
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end write_instr;
|
||||
|
||||
|
||||
end dlx_instr;
|
||||
@@ -0,0 +1,257 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx_instr.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 22:34:41 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Package specification for DLX instructions
|
||||
--
|
||||
|
||||
|
||||
use std.textio.line,
|
||||
work.dlx_types.all;
|
||||
|
||||
package dlx_instr is
|
||||
|
||||
-- A dlx instruction is 32 bits wide. There are three instruction formats:
|
||||
--
|
||||
-- I-type:
|
||||
-- 0 5 6 10 11 15 16 31
|
||||
-- +----------------------------------------------------------------+
|
||||
-- | opcode | rs1 | rd | immed16 |
|
||||
-- +----------------------------------------------------------------+
|
||||
--
|
||||
-- R-type:
|
||||
-- 0 5 6 10 11 15 16 20 21 25 26 31
|
||||
-- +----------------------------------------------------------------+
|
||||
-- | opcode | rs1 | rs2 | rd | | func |
|
||||
-- +----------------------------------------------------------------+
|
||||
--
|
||||
-- J-type:
|
||||
-- 0 5 6 31
|
||||
-- +----------------------------------------------------------------+
|
||||
-- | opcode | immed26 |
|
||||
-- +----------------------------------------------------------------+
|
||||
--
|
||||
|
||||
subtype dlx_opcode is bit_vector(0 to 5);
|
||||
subtype dlx_sp_func is bit_vector(0 to 5);
|
||||
subtype dlx_fp_func is bit_vector(0 to 4);
|
||||
subtype dlx_reg_addr is bit_vector(0 to 4);
|
||||
subtype dlx_immed16 is bit_vector(0 to 15);
|
||||
subtype dlx_immed26 is bit_vector(0 to 25);
|
||||
|
||||
|
||||
constant op_special : dlx_opcode := B"000000";
|
||||
constant op_fparith : dlx_opcode := B"000001";
|
||||
constant op_j : dlx_opcode := B"000010";
|
||||
constant op_jal : dlx_opcode := B"000011";
|
||||
constant op_beqz : dlx_opcode := B"000100";
|
||||
constant op_bnez : dlx_opcode := B"000101";
|
||||
constant op_bfpt : dlx_opcode := B"000110";
|
||||
constant op_bfpf : dlx_opcode := B"000111";
|
||||
constant op_addi : dlx_opcode := B"001000";
|
||||
constant op_addui : dlx_opcode := B"001001";
|
||||
constant op_subi : dlx_opcode := B"001010";
|
||||
constant op_subui : dlx_opcode := B"001011";
|
||||
constant op_andi : dlx_opcode := B"001100";
|
||||
constant op_ori : dlx_opcode := B"001101";
|
||||
constant op_xori : dlx_opcode := B"001110";
|
||||
constant op_lhi : dlx_opcode := B"001111";
|
||||
|
||||
constant op_rfe : dlx_opcode := B"010000";
|
||||
constant op_trap : dlx_opcode := B"010001";
|
||||
constant op_jr : dlx_opcode := B"010010";
|
||||
constant op_jalr : dlx_opcode := B"010011";
|
||||
constant op_slli : dlx_opcode := B"010100";
|
||||
constant op_undef_15 : dlx_opcode := B"010101";
|
||||
constant op_srli : dlx_opcode := B"010110";
|
||||
constant op_srai : dlx_opcode := B"010111";
|
||||
constant op_seqi : dlx_opcode := B"011000";
|
||||
constant op_snei : dlx_opcode := B"011001";
|
||||
constant op_slti : dlx_opcode := B"011010";
|
||||
constant op_sgti : dlx_opcode := B"011011";
|
||||
constant op_slei : dlx_opcode := B"011100";
|
||||
constant op_sgei : dlx_opcode := B"011101";
|
||||
constant op_undef_1E : dlx_opcode := B"011110";
|
||||
constant op_undef_1F : dlx_opcode := B"011111";
|
||||
|
||||
constant op_lb : dlx_opcode := B"100000";
|
||||
constant op_lh : dlx_opcode := B"100001";
|
||||
constant op_undef_22 : dlx_opcode := B"100010";
|
||||
constant op_lw : dlx_opcode := B"100011";
|
||||
constant op_lbu : dlx_opcode := B"100100";
|
||||
constant op_lhu : dlx_opcode := B"100101";
|
||||
constant op_lf : dlx_opcode := B"100110";
|
||||
constant op_ld : dlx_opcode := B"100111";
|
||||
constant op_sb : dlx_opcode := B"101000";
|
||||
constant op_sh : dlx_opcode := B"101001";
|
||||
constant op_undef_2A : dlx_opcode := B"101010";
|
||||
constant op_sw : dlx_opcode := B"101011";
|
||||
constant op_undef_2C : dlx_opcode := B"101100";
|
||||
constant op_undef_2D : dlx_opcode := B"101101";
|
||||
constant op_sf : dlx_opcode := B"101110";
|
||||
constant op_sd : dlx_opcode := B"101111";
|
||||
|
||||
constant op_sequi : dlx_opcode := B"110000";
|
||||
constant op_sneui : dlx_opcode := B"110001";
|
||||
constant op_sltui : dlx_opcode := B"110010";
|
||||
constant op_sgtui : dlx_opcode := B"110011";
|
||||
constant op_sleui : dlx_opcode := B"110100";
|
||||
constant op_sgeui : dlx_opcode := B"110101";
|
||||
constant op_undef_36 : dlx_opcode := B"110110";
|
||||
constant op_undef_37 : dlx_opcode := B"110111";
|
||||
constant op_undef_38 : dlx_opcode := B"111000";
|
||||
constant op_undef_39 : dlx_opcode := B"111001";
|
||||
constant op_undef_3A : dlx_opcode := B"111010";
|
||||
constant op_undef_3B : dlx_opcode := B"111011";
|
||||
constant op_undef_3C : dlx_opcode := B"111100";
|
||||
constant op_undef_3D : dlx_opcode := B"111101";
|
||||
constant op_undef_3E : dlx_opcode := B"111110";
|
||||
constant op_undef_3F : dlx_opcode := B"111111";
|
||||
|
||||
constant sp_func_nop : dlx_sp_func := B"000000";
|
||||
constant sp_func_undef_01 : dlx_sp_func := B"000001";
|
||||
constant sp_func_undef_02 : dlx_sp_func := B"000010";
|
||||
constant sp_func_undef_03 : dlx_sp_func := B"000011";
|
||||
constant sp_func_sll : dlx_sp_func := B"000100";
|
||||
constant sp_func_undef_05 : dlx_sp_func := B"000101";
|
||||
constant sp_func_srl : dlx_sp_func := B"000110";
|
||||
constant sp_func_sra : dlx_sp_func := B"000111";
|
||||
constant sp_func_undef_08 : dlx_sp_func := B"001000";
|
||||
constant sp_func_undef_09 : dlx_sp_func := B"001001";
|
||||
constant sp_func_undef_0A : dlx_sp_func := B"001010";
|
||||
constant sp_func_undef_0B : dlx_sp_func := B"001011";
|
||||
constant sp_func_undef_0C : dlx_sp_func := B"001100";
|
||||
constant sp_func_undef_0D : dlx_sp_func := B"001101";
|
||||
constant sp_func_undef_0E : dlx_sp_func := B"001110";
|
||||
constant sp_func_undef_0F : dlx_sp_func := B"001111";
|
||||
|
||||
constant sp_func_sequ : dlx_sp_func := B"010000";
|
||||
constant sp_func_sneu : dlx_sp_func := B"010001";
|
||||
constant sp_func_sltu : dlx_sp_func := B"010010";
|
||||
constant sp_func_sgtu : dlx_sp_func := B"010011";
|
||||
constant sp_func_sleu : dlx_sp_func := B"010100";
|
||||
constant sp_func_sgeu : dlx_sp_func := B"010101";
|
||||
constant sp_func_undef_16 : dlx_sp_func := B"010110";
|
||||
constant sp_func_undef_17 : dlx_sp_func := B"010111";
|
||||
constant sp_func_undef_18 : dlx_sp_func := B"011000";
|
||||
constant sp_func_undef_19 : dlx_sp_func := B"011001";
|
||||
constant sp_func_undef_1A : dlx_sp_func := B"011010";
|
||||
constant sp_func_undef_1B : dlx_sp_func := B"011011";
|
||||
constant sp_func_undef_1C : dlx_sp_func := B"011100";
|
||||
constant sp_func_undef_1D : dlx_sp_func := B"011101";
|
||||
constant sp_func_undef_1E : dlx_sp_func := B"011110";
|
||||
constant sp_func_undef_1F : dlx_sp_func := B"011111";
|
||||
|
||||
constant sp_func_add : dlx_sp_func := B"100000";
|
||||
constant sp_func_addu : dlx_sp_func := B"100001";
|
||||
constant sp_func_sub : dlx_sp_func := B"100010";
|
||||
constant sp_func_subu : dlx_sp_func := B"100011";
|
||||
constant sp_func_and : dlx_sp_func := B"100100";
|
||||
constant sp_func_or : dlx_sp_func := B"100101";
|
||||
constant sp_func_xor : dlx_sp_func := B"100110";
|
||||
constant sp_func_undef_27 : dlx_sp_func := B"100111";
|
||||
constant sp_func_seq : dlx_sp_func := B"101000";
|
||||
constant sp_func_sne : dlx_sp_func := B"101001";
|
||||
constant sp_func_slt : dlx_sp_func := B"101010";
|
||||
constant sp_func_sgt : dlx_sp_func := B"101011";
|
||||
constant sp_func_sle : dlx_sp_func := B"101100";
|
||||
constant sp_func_sge : dlx_sp_func := B"101101";
|
||||
constant sp_func_undef_2E : dlx_sp_func := B"101110";
|
||||
constant sp_func_undef_2F : dlx_sp_func := B"101111";
|
||||
|
||||
constant sp_func_movi2s : dlx_sp_func := B"110000";
|
||||
constant sp_func_movs2i : dlx_sp_func := B"110001";
|
||||
constant sp_func_movf : dlx_sp_func := B"110010";
|
||||
constant sp_func_movd : dlx_sp_func := B"110011";
|
||||
constant sp_func_movfp2i : dlx_sp_func := B"110100";
|
||||
constant sp_func_movi2fp : dlx_sp_func := B"110101";
|
||||
constant sp_func_undef_36 : dlx_sp_func := B"110110";
|
||||
constant sp_func_undef_37 : dlx_sp_func := B"110111";
|
||||
constant sp_func_undef_38 : dlx_sp_func := B"111000";
|
||||
constant sp_func_undef_39 : dlx_sp_func := B"111001";
|
||||
constant sp_func_undef_3A : dlx_sp_func := B"111010";
|
||||
constant sp_func_undef_3B : dlx_sp_func := B"111011";
|
||||
constant sp_func_undef_3C : dlx_sp_func := B"111100";
|
||||
constant sp_func_undef_3D : dlx_sp_func := B"111101";
|
||||
constant sp_func_undef_3E : dlx_sp_func := B"111110";
|
||||
constant sp_func_undef_3F : dlx_sp_func := B"111111";
|
||||
|
||||
constant fp_func_addf : dlx_fp_func := B"00000";
|
||||
constant fp_func_subf : dlx_fp_func := B"00001";
|
||||
constant fp_func_multf : dlx_fp_func := B"00010";
|
||||
constant fp_func_divf : dlx_fp_func := B"00011";
|
||||
constant fp_func_addd : dlx_fp_func := B"00100";
|
||||
constant fp_func_subd : dlx_fp_func := B"00101";
|
||||
constant fp_func_multd : dlx_fp_func := B"00110";
|
||||
constant fp_func_divd : dlx_fp_func := B"00111";
|
||||
constant fp_func_cvtf2d : dlx_fp_func := B"01000";
|
||||
constant fp_func_cvtf2i : dlx_fp_func := B"01001";
|
||||
constant fp_func_cvtd2f : dlx_fp_func := B"01010";
|
||||
constant fp_func_cvtd2i : dlx_fp_func := B"01011";
|
||||
constant fp_func_cvti2f : dlx_fp_func := B"01100";
|
||||
constant fp_func_cvti2d : dlx_fp_func := B"01101";
|
||||
constant fp_func_mult : dlx_fp_func := B"01110";
|
||||
constant fp_func_div : dlx_fp_func := B"01111";
|
||||
|
||||
constant fp_func_eqf : dlx_fp_func := B"10000";
|
||||
constant fp_func_nef : dlx_fp_func := B"10001";
|
||||
constant fp_func_ltf : dlx_fp_func := B"10010";
|
||||
constant fp_func_gtf : dlx_fp_func := B"10011";
|
||||
constant fp_func_lef : dlx_fp_func := B"10100";
|
||||
constant fp_func_gef : dlx_fp_func := B"10101";
|
||||
constant fp_func_multu : dlx_fp_func := B"10110";
|
||||
constant fp_func_divu : dlx_fp_func := B"10111";
|
||||
constant fp_func_eqd : dlx_fp_func := B"11000";
|
||||
constant fp_func_ned : dlx_fp_func := B"11001";
|
||||
constant fp_func_ltd : dlx_fp_func := B"11010";
|
||||
constant fp_func_gtd : dlx_fp_func := B"11011";
|
||||
constant fp_func_led : dlx_fp_func := B"11100";
|
||||
constant fp_func_ged : dlx_fp_func := B"11101";
|
||||
constant fp_func_undef_1E : dlx_fp_func := B"11110";
|
||||
constant fp_func_undef_1F : dlx_fp_func := B"11111";
|
||||
|
||||
subtype dlx_opcode_num is natural range 0 to 63;
|
||||
subtype dlx_sp_func_num is natural range 0 to 63;
|
||||
subtype dlx_fp_func_num is natural range 0 to 31;
|
||||
|
||||
subtype instr_name is string(1 to 8);
|
||||
type opcode_name_array is array (dlx_opcode_num) of instr_name;
|
||||
type sp_func_name_array is array (dlx_sp_func_num) of instr_name;
|
||||
type fp_func_name_array is array (dlx_fp_func_num) of instr_name;
|
||||
|
||||
constant opcode_names : opcode_name_array;
|
||||
constant sp_func_names : sp_func_name_array;
|
||||
constant fp_func_names : fp_func_name_array;
|
||||
|
||||
type immed_size is (immed_size_16, immed_size_26);
|
||||
|
||||
subtype reg_index is natural range 0 to 31;
|
||||
|
||||
constant link_reg : reg_index := 31;
|
||||
|
||||
procedure write_instr (L : inout line; instr : in dlx_word);
|
||||
|
||||
end dlx_instr;
|
||||
@@ -0,0 +1,104 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx_test-bench.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 22:40:43 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Architecture for test bench for DLX,
|
||||
-- consisting of clock generator, memory and bus_monitor
|
||||
--
|
||||
|
||||
|
||||
use std.textio.all,
|
||||
work.dlx_types.all, work.mem_types.all;
|
||||
|
||||
architecture bench of dlx_test is
|
||||
|
||||
component clock_gen
|
||||
port (phi1, phi2 : out bit;
|
||||
reset : out bit);
|
||||
end component;
|
||||
|
||||
component memory
|
||||
port (phi1, phi2 : in bit;
|
||||
a : in dlx_address;
|
||||
d : inout dlx_word_bus bus;
|
||||
width : in mem_width;
|
||||
write_enable : in bit;
|
||||
burst : in bit := '0';
|
||||
mem_enable : in bit;
|
||||
ready : out bit);
|
||||
end component;
|
||||
|
||||
component dlx
|
||||
port (phi1, phi2 : in bit; -- 2-phase non-overlapping clocks
|
||||
reset : in bit; -- synchronous reset input
|
||||
a : out dlx_address; -- address bus output
|
||||
d : inout dlx_word_bus bus; -- bidirectional data bus
|
||||
halt : out bit; -- halt indicator
|
||||
width : out mem_width; -- byte/haldword/word indicator
|
||||
write_enable : out bit; -- selects read or write cycle
|
||||
mem_enable : out bit; -- starts memory cycle
|
||||
ifetch : out bit; -- indicates instruction fetch
|
||||
ready : in bit); -- status from memory system
|
||||
end component;
|
||||
|
||||
component dlx_bus_monitor
|
||||
port (phi1, phi2 : in bit; -- 2-phase non-overlapping clocks
|
||||
reset : in bit; -- synchronous reset
|
||||
a : in dlx_address; -- address bus
|
||||
d : in dlx_word; -- data bus
|
||||
halt : in bit; -- halt indicator
|
||||
width : in mem_width; -- byte/haldword/word indicator
|
||||
write_enable : in bit; -- selects read or write cycle
|
||||
burst : in bit := '0'; -- indicates more to come in burst
|
||||
mem_enable : in bit; -- starts memory cycle
|
||||
ifetch : in bit; -- indicates instruction fetch
|
||||
ready : in bit); -- status from memory system
|
||||
end component;
|
||||
|
||||
signal phi1, phi2, reset : bit;
|
||||
signal a : dlx_address;
|
||||
signal d : dlx_word_bus bus;
|
||||
signal halt : bit;
|
||||
signal width : mem_width;
|
||||
signal write_enable, mem_enable, ifetch, ready : bit;
|
||||
|
||||
begin
|
||||
|
||||
cg : clock_gen
|
||||
port map (phi1, phi2, reset);
|
||||
|
||||
mem : memory
|
||||
port map (phi1, phi2, a, d, width, write_enable, open, mem_enable, ready);
|
||||
|
||||
proc : dlx
|
||||
port map (phi1, phi2, reset, a, d,
|
||||
halt, width, write_enable, mem_enable, ifetch, ready);
|
||||
|
||||
bus_monitor : dlx_bus_monitor
|
||||
port map (phi1, phi2, reset, a, d,
|
||||
halt, width, write_enable, open, mem_enable, ifetch, ready);
|
||||
|
||||
end bench;
|
||||
@@ -0,0 +1,139 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx_test-bench_cache.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 22:14:11 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Architecture for test bench for DLX and cache, including clock generator,
|
||||
-- memory and bus monitors for both CPU/cache and cache/memory buses.
|
||||
--
|
||||
|
||||
|
||||
use std.textio.all,
|
||||
work.dlx_types.all,
|
||||
work.mem_types.all;
|
||||
|
||||
|
||||
architecture bench_cache of dlx_test is
|
||||
|
||||
component clock_gen
|
||||
port (phi1, phi2 : out bit;
|
||||
reset : out bit);
|
||||
end component;
|
||||
|
||||
component memory
|
||||
port (phi1, phi2 : in bit;
|
||||
a : in dlx_address;
|
||||
d : inout dlx_word_bus bus;
|
||||
width : in mem_width;
|
||||
write_enable : in bit;
|
||||
burst : in bit := '0';
|
||||
mem_enable : in bit;
|
||||
ready : out bit);
|
||||
end component;
|
||||
|
||||
component dlx
|
||||
port (phi1, phi2 : in bit; -- 2-phase non-overlapping clocks
|
||||
reset : in bit; -- synchronous reset input
|
||||
a : out dlx_address; -- address bus output
|
||||
d : inout dlx_word_bus bus; -- bidirectional data bus
|
||||
halt : out bit; -- halt indicator
|
||||
width : out mem_width; -- byte/haldword/word indicator
|
||||
write_enable : out bit; -- selects read or write cycle
|
||||
mem_enable : out bit; -- starts memory cycle
|
||||
ifetch : out bit; -- indicates instruction fetch
|
||||
ready : in bit); -- status from memory system
|
||||
end component;
|
||||
|
||||
component cache
|
||||
port (phi1, phi2 : in bit; -- 2-phase non-overlapping clocks
|
||||
reset : in bit; -- synchronous reset input
|
||||
-- connections to CPU
|
||||
cpu_enable : in bit; -- starts memory cycle
|
||||
cpu_width : in mem_width; -- byte/halfword/word indicator
|
||||
cpu_write : in bit; -- selects read or write cycle
|
||||
cpu_ready : out bit; -- status from memory system
|
||||
cpu_a : in dlx_address; -- address bus output
|
||||
cpu_d : inout dlx_word_bus bus; -- bidirectional data bus
|
||||
-- connections to memory
|
||||
mem_enable : out bit; -- starts memory cycle
|
||||
mem_width : out mem_width; -- byte/halfword/word indicator
|
||||
mem_write : out bit; -- selects read or write cycle
|
||||
mem_burst : out bit; -- tell memory to burst txfer
|
||||
mem_ready : in bit; -- status from memory system
|
||||
mem_a : out dlx_address; -- address bus output
|
||||
mem_d : inout dlx_word_bus bus); -- bidirectional data bus
|
||||
end component;
|
||||
|
||||
component dlx_bus_monitor
|
||||
port (phi1, phi2 : in bit; -- 2-phase non-overlapping clocks
|
||||
reset : in bit; -- synchronous reset
|
||||
a : in dlx_address; -- address bus
|
||||
d : in dlx_word; -- data bus
|
||||
halt : in bit; -- halt indicator
|
||||
width : in mem_width; -- byte/haldword/word indicator
|
||||
write_enable : in bit; -- selects read or write cycle
|
||||
burst : in bit := '0'; -- indicates more to come in burst
|
||||
mem_enable : in bit; -- starts memory cycle
|
||||
ifetch : in bit; -- indicates instruction fetch
|
||||
ready : in bit); -- status from memory system
|
||||
end component;
|
||||
|
||||
signal phi1, phi2, reset : bit;
|
||||
signal cpu_a, mem_a : dlx_address;
|
||||
signal cpu_d, mem_d : dlx_word_bus bus;
|
||||
signal halt : bit;
|
||||
signal cpu_width, mem_width : mem_width;
|
||||
signal cpu_enable, mem_enable,
|
||||
cpu_write, mem_write,
|
||||
cpu_ready, mem_ready,
|
||||
mem_burst, ifetch : bit;
|
||||
|
||||
begin
|
||||
|
||||
cg : clock_gen
|
||||
port map (phi1, phi2, reset);
|
||||
|
||||
mem : memory
|
||||
port map (phi1, phi2, mem_a, mem_d,
|
||||
mem_width, mem_write, mem_burst, mem_enable, mem_ready);
|
||||
|
||||
proc : dlx
|
||||
port map (phi1, phi2, reset, cpu_a, cpu_d,
|
||||
halt, cpu_width, cpu_write, cpu_enable, ifetch, cpu_ready);
|
||||
|
||||
the_cache : cache
|
||||
port map (phi1, phi2, reset,
|
||||
cpu_enable, cpu_width, cpu_write, cpu_ready, cpu_a, cpu_d,
|
||||
mem_enable, mem_width, mem_write, mem_burst, mem_ready, mem_a, mem_d);
|
||||
|
||||
cpu_cache_monitor : dlx_bus_monitor
|
||||
port map (phi1, phi2, reset, cpu_a, cpu_d,
|
||||
halt, cpu_width, cpu_write, open, cpu_enable, ifetch, cpu_ready);
|
||||
|
||||
cache_mem_monitor : dlx_bus_monitor
|
||||
port map (phi1, phi2, reset, mem_a, mem_d,
|
||||
halt, mem_width, mem_write, mem_burst, mem_enable, ifetch, mem_ready);
|
||||
|
||||
end bench_cache;
|
||||
@@ -0,0 +1,33 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx_test.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 22:39:49 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for test bench for DLX
|
||||
--
|
||||
|
||||
|
||||
entity dlx_test is
|
||||
end dlx_test;
|
||||
@@ -0,0 +1,59 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx_test_behaviour.vhdl,v $ $Revision: 2.2 $ $Date: 1993/11/02 17:59:08 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Configuration of test bench for DLX, using architecture behaviour
|
||||
--
|
||||
|
||||
|
||||
configuration dlx_test_behaviour of dlx_test is
|
||||
|
||||
for bench
|
||||
|
||||
for cg : clock_gen
|
||||
use entity work.clock_gen(behaviour)
|
||||
generic map (Tpw => 8 ns, Tps => 2 ns);
|
||||
end for;
|
||||
|
||||
for mem : memory
|
||||
use entity work.memory(behaviour)
|
||||
generic map (mem_size => 65536,
|
||||
Tac1 => 95 ns, Tacb => 35 ns, Tpd_clk_out => 2 ns);
|
||||
end for;
|
||||
|
||||
for bus_monitor : dlx_bus_monitor
|
||||
use entity work.dlx_bus_monitor(behaviour)
|
||||
generic map (enable => true, verbose => false, tag => "bus monitor");
|
||||
end for;
|
||||
|
||||
for proc : dlx
|
||||
use entity work.dlx(behaviour)
|
||||
generic map (Tpd_clk_out => 2 ns, debug => true, tag => "proc");
|
||||
end for;
|
||||
|
||||
end for;
|
||||
|
||||
end dlx_test_behaviour;
|
||||
@@ -0,0 +1,74 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx_test_cache.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 22:16:15 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Configuration of test bench for DLX and cache,
|
||||
-- using behavioural architectures.
|
||||
--
|
||||
|
||||
|
||||
configuration dlx_test_cache of dlx_test is
|
||||
|
||||
for bench_cache
|
||||
|
||||
use work.cache_types.all;
|
||||
|
||||
for cg : clock_gen
|
||||
use entity work.clock_gen(behaviour)
|
||||
generic map (Tpw => 8 ns, Tps => 2 ns);
|
||||
end for;
|
||||
|
||||
for mem : memory
|
||||
use entity work.memory(behaviour)
|
||||
generic map (mem_size => 65536,
|
||||
Tac1 => 95 ns, Tacb => 35 ns, Tpd_clk_out => 2 ns);
|
||||
end for;
|
||||
|
||||
for the_cache : cache
|
||||
use entity work.cache(behaviour)
|
||||
generic map (cache_size => 4096, line_size => 16,
|
||||
associativity => 2, write_strategy => write_through,
|
||||
Tpd_clk_out => 2 ns);
|
||||
end for;
|
||||
|
||||
for cpu_cache_monitor : dlx_bus_monitor
|
||||
use entity work.dlx_bus_monitor(behaviour)
|
||||
generic map (enable => true, verbose => false, tag => "cpu cache monitor");
|
||||
end for;
|
||||
|
||||
for cache_mem_monitor : dlx_bus_monitor
|
||||
use entity work.dlx_bus_monitor(behaviour)
|
||||
generic map (enable => true, verbose => false, tag => "cache mem monitor");
|
||||
end for;
|
||||
|
||||
for proc : dlx
|
||||
use entity work.dlx(behaviour)
|
||||
generic map (Tpd_clk_out => 2 ns, debug => false, tag => "proc");
|
||||
end for;
|
||||
|
||||
end for;
|
||||
|
||||
end dlx_test_cache;
|
||||
@@ -0,0 +1,60 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx_test_instrumented.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 18:37:44 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Configuration of test bench for DLX, using instrumented
|
||||
-- architecture of CPU and empty architecture of bus monitor.
|
||||
--
|
||||
|
||||
|
||||
configuration dlx_test_instrumented of dlx_test is
|
||||
|
||||
for bench
|
||||
|
||||
for cg : clock_gen
|
||||
use entity work.clock_gen(behaviour)
|
||||
generic map (Tpw => 8 ns, Tps => 2 ns);
|
||||
end for;
|
||||
|
||||
for mem : memory
|
||||
use entity work.memory(behaviour)
|
||||
generic map (mem_size => 65536,
|
||||
Tac1 => 95 ns, Tacb => 35 ns, Tpd_clk_out => 2 ns);
|
||||
end for;
|
||||
|
||||
for bus_monitor : dlx_bus_monitor
|
||||
use entity work.dlx_bus_monitor(behaviour)
|
||||
generic map (enable => false);
|
||||
end for;
|
||||
|
||||
for proc : dlx
|
||||
use entity work.dlx(instrumented)
|
||||
generic map (Tpd_clk_out => 2 ns, debug => false, tag => "proc");
|
||||
end for;
|
||||
|
||||
end for;
|
||||
|
||||
end dlx_test_instrumented;
|
||||
@@ -0,0 +1,103 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx_test_rtl.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 20:20:00 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Configuration of DLX test bench using register transfer level
|
||||
-- architecture of DLX processor.
|
||||
--
|
||||
|
||||
|
||||
configuration dlx_test_rtl of dlx_test is
|
||||
|
||||
for bench
|
||||
|
||||
for cg : clock_gen
|
||||
use entity work.clock_gen(behaviour)
|
||||
generic map (Tpw => 8 ns, Tps => 2 ns);
|
||||
end for;
|
||||
|
||||
for mem : memory
|
||||
use entity work.memory(behaviour)
|
||||
generic map (mem_size => 65536,
|
||||
Tac1 => 95 ns, Tacb => 35 ns, Tpd_clk_out => 2 ns);
|
||||
end for;
|
||||
|
||||
for bus_monitor : dlx_bus_monitor
|
||||
use entity work.dlx_bus_monitor(behaviour)
|
||||
generic map (enable => true, verbose => true, tag => "bus monitor");
|
||||
end for;
|
||||
|
||||
for proc : dlx
|
||||
use entity work.dlx(rtl)
|
||||
generic map (Tpd_clk_out => 2 ns, debug => true, tag => "proc");
|
||||
for rtl
|
||||
for all : alu
|
||||
use entity work.alu(behaviour)
|
||||
generic map (Tpd => 4 ns);
|
||||
end for;
|
||||
for all : reg_file
|
||||
use entity work.reg_file(behaviour)
|
||||
generic map (Tac => 4 ns);
|
||||
end for;
|
||||
for all : latch
|
||||
use entity work.latch(behaviour)
|
||||
generic map (Tpd => 2 ns);
|
||||
end for;
|
||||
for all : reg_1_out
|
||||
use entity work.reg_1_out(behaviour)
|
||||
generic map (Tpd => 2 ns);
|
||||
end for;
|
||||
for all : reg_2_out
|
||||
use entity work.reg_2_out(behaviour)
|
||||
generic map (Tpd => 2 ns);
|
||||
end for;
|
||||
for all : reg_2_1_out
|
||||
use entity work.reg_2_1_out(behaviour)
|
||||
generic map (Tpd => 2 ns);
|
||||
end for;
|
||||
for all : reg_3_out
|
||||
use entity work.reg_3_out(behaviour)
|
||||
generic map (Tpd => 2 ns);
|
||||
end for;
|
||||
for all : mux2
|
||||
use entity work.mux2(behaviour)
|
||||
generic map (Tpd => 1 ns);
|
||||
end for;
|
||||
for all : ir
|
||||
use entity work.ir(behaviour)
|
||||
generic map (Tpd => 2 ns);
|
||||
end for;
|
||||
for the_controller : controller
|
||||
use entity work.controller(behaviour)
|
||||
generic map (Tpd_clk_ctrl => 2 ns, Tpd_clk_const => 4 ns,
|
||||
debug => true);
|
||||
end for;
|
||||
end for; -- rtl of dlx
|
||||
end for; -- proc : dlx
|
||||
|
||||
end for; -- bench of dlx_test
|
||||
|
||||
end dlx_test_rtl;
|
||||
@@ -0,0 +1,45 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx_types-body.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 20:37:38 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Package body for types used in dlx model
|
||||
--
|
||||
|
||||
|
||||
package body dlx_types is
|
||||
|
||||
function resolve_dlx_word (values : in dlx_word_array) return dlx_word is
|
||||
|
||||
variable result : dlx_word := X"0000_0000";
|
||||
|
||||
begin
|
||||
for i in values'range loop
|
||||
result := result or values(i);
|
||||
end loop;
|
||||
return result;
|
||||
end resolve_dlx_word;
|
||||
|
||||
end dlx_types;
|
||||
@@ -0,0 +1,44 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: dlx_types.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 20:35:20 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Package specification for types used in dlx model
|
||||
--
|
||||
|
||||
|
||||
package dlx_types is
|
||||
|
||||
subtype dlx_word is bit_vector(0 to 31); -- bit 0 is msb
|
||||
subtype dlx_halfword is bit_vector(0 to 15); -- bit 0 is msb
|
||||
subtype dlx_byte is bit_vector(0 to 7); -- bit 0 is msb
|
||||
|
||||
type dlx_word_array is array (positive range <>) of dlx_word;
|
||||
function resolve_dlx_word (values : in dlx_word_array) return dlx_word;
|
||||
subtype dlx_word_bus is resolve_dlx_word dlx_word;
|
||||
|
||||
subtype dlx_address is bit_vector(31 downto 0); -- bit 0 is lsb
|
||||
|
||||
end dlx_types;
|
||||
@@ -0,0 +1,167 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: images-body.vhdl,v $ $Revision: 1.1 $ $Date: 1993/10/25 20:46:18 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Images package body.
|
||||
--
|
||||
-- Functions that return the string image of values.
|
||||
-- Each image is a correctly formed literal according to the
|
||||
-- rules of VHDL-93.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
package body images is
|
||||
|
||||
|
||||
-- Image of bit vector as binary bit string literal
|
||||
-- (in the format B"...")
|
||||
-- Length of result is bv'length + 3
|
||||
|
||||
function image (bv : in bit_vector) return string is
|
||||
|
||||
alias bv_norm : bit_vector(1 to bv'length) is bv;
|
||||
variable result : string(1 to bv'length + 3);
|
||||
|
||||
begin
|
||||
result(1) := 'B';
|
||||
result(2) := '"';
|
||||
for index in bv_norm'range loop
|
||||
if bv_norm(index) = '0' then
|
||||
result(index + 2) := '0';
|
||||
else
|
||||
result(index + 2) := '1';
|
||||
end if;
|
||||
end loop;
|
||||
result(bv'length + 3) := '"';
|
||||
return result;
|
||||
end image;
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
-- Image of bit vector as octal bit string literal
|
||||
-- (in the format O"...")
|
||||
-- Length of result is (bv'length+2)/3 + 3
|
||||
|
||||
function image_octal (bv : in bit_vector) return string is
|
||||
|
||||
constant nr_digits : natural := (bv'length + 2) / 3;
|
||||
variable result : string(1 to nr_digits + 3);
|
||||
variable bits : bit_vector(0 to 3*nr_digits - 1) := (others => '0');
|
||||
variable three_bits : bit_vector(0 to 2);
|
||||
variable digit : character;
|
||||
|
||||
begin
|
||||
result(1) := 'O';
|
||||
result(2) := '"';
|
||||
bits(bits'right - bv'length + 1 to bits'right) := bv;
|
||||
for index in 0 to nr_digits - 1 loop
|
||||
three_bits := bits(3*index to 3*index + 2);
|
||||
case three_bits is
|
||||
when b"000" =>
|
||||
digit := '0';
|
||||
when b"001" =>
|
||||
digit := '1';
|
||||
when b"010" =>
|
||||
digit := '2';
|
||||
when b"011" =>
|
||||
digit := '3';
|
||||
when b"100" =>
|
||||
digit := '4';
|
||||
when b"101" =>
|
||||
digit := '5';
|
||||
when b"110" =>
|
||||
digit := '6';
|
||||
when b"111" =>
|
||||
digit := '7';
|
||||
end case;
|
||||
result(index + 3) := digit;
|
||||
end loop;
|
||||
result(nr_digits + 3) := '"';
|
||||
return result;
|
||||
end image_octal;
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
-- Image of bit vector as hex bit string literal
|
||||
-- (in the format X"...")
|
||||
-- Length of result is (bv'length+3)/4 + 3
|
||||
|
||||
function image_hex (bv : in bit_vector) return string is
|
||||
|
||||
constant nr_digits : natural := (bv'length + 3) / 4;
|
||||
variable result : string(1 to nr_digits + 3);
|
||||
variable bits : bit_vector(0 to 4*nr_digits - 1) := (others => '0');
|
||||
variable four_bits : bit_vector(0 to 3);
|
||||
variable digit : character;
|
||||
|
||||
begin
|
||||
result(1) := 'X';
|
||||
result(2) := '"';
|
||||
bits(bits'right - bv'length + 1 to bits'right) := bv;
|
||||
for index in 0 to nr_digits - 1 loop
|
||||
four_bits := bits(4*index to 4*index + 3);
|
||||
case four_bits is
|
||||
when b"0000" =>
|
||||
digit := '0';
|
||||
when b"0001" =>
|
||||
digit := '1';
|
||||
when b"0010" =>
|
||||
digit := '2';
|
||||
when b"0011" =>
|
||||
digit := '3';
|
||||
when b"0100" =>
|
||||
digit := '4';
|
||||
when b"0101" =>
|
||||
digit := '5';
|
||||
when b"0110" =>
|
||||
digit := '6';
|
||||
when b"0111" =>
|
||||
digit := '7';
|
||||
when b"1000" =>
|
||||
digit := '8';
|
||||
when b"1001" =>
|
||||
digit := '9';
|
||||
when b"1010" =>
|
||||
digit := 'A';
|
||||
when b"1011" =>
|
||||
digit := 'B';
|
||||
when b"1100" =>
|
||||
digit := 'C';
|
||||
when b"1101" =>
|
||||
digit := 'D';
|
||||
when b"1110" =>
|
||||
digit := 'E';
|
||||
when b"1111" =>
|
||||
digit := 'F';
|
||||
end case;
|
||||
result(index + 3) := digit;
|
||||
end loop;
|
||||
result(nr_digits + 3) := '"';
|
||||
return result;
|
||||
end image_hex;
|
||||
|
||||
|
||||
end images;
|
||||
@@ -0,0 +1,61 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: images.vhdl,v $ $Revision: 1.1 $ $Date: 1993/10/25 20:45:45 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Images package specification.
|
||||
--
|
||||
-- Functions that return the string image of values.
|
||||
-- Each image is a correctly formed literal according to the
|
||||
-- rules of VHDL-93.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
package images is
|
||||
|
||||
|
||||
-- Image of bit vector as binary bit string literal
|
||||
-- (in the format B"...")
|
||||
-- Length of result is bv'length + 3
|
||||
|
||||
function image (bv : in bit_vector) return string;
|
||||
|
||||
|
||||
-- Image of bit vector as octal bit string literal
|
||||
-- (in the format O"...")
|
||||
-- Length of result is (bv'length+2)/3 + 3
|
||||
|
||||
function image_octal (bv : in bit_vector) return string;
|
||||
|
||||
|
||||
-- Image of bit vector as hex bit string literal
|
||||
-- (in the format X"...")
|
||||
-- Length of result is (bv'length+3)/4 + 3
|
||||
|
||||
function image_hex (bv : in bit_vector) return string;
|
||||
|
||||
|
||||
end images;
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: images_test-bench.vhdl,v $ $Revision: 1.1 $ $Date: 1993/10/25 20:47:40 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Architecture declaration for test bench for images package
|
||||
--
|
||||
|
||||
use std.textio.all;
|
||||
|
||||
use work.images.all;
|
||||
|
||||
architecture bench of images_test is
|
||||
|
||||
begin
|
||||
|
||||
process
|
||||
|
||||
variable L : line;
|
||||
|
||||
begin
|
||||
----------------------------------------------------------------
|
||||
-- Test binary image of a bit vector
|
||||
----------------------------------------------------------------
|
||||
write(L, image(b"01"));
|
||||
writeline(output, L);
|
||||
write(L, image(b"01011010"));
|
||||
writeline(output, L);
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Test octal image of a bit vector
|
||||
----------------------------------------------------------------
|
||||
write(L, image_octal(o"05"));
|
||||
writeline(output, L);
|
||||
write(L, image_octal(o"370"));
|
||||
writeline(output, L);
|
||||
write(L, image_octal(b"1"));
|
||||
writeline(output, L);
|
||||
write(L, image_octal(b"11000"));
|
||||
writeline(output, L);
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Test hex image of a bit vector
|
||||
----------------------------------------------------------------
|
||||
write(L, image_hex(x"0C"));
|
||||
writeline(output, L);
|
||||
write(L, image_hex(x"F1"));
|
||||
writeline(output, L);
|
||||
write(L, image_hex("1"));
|
||||
writeline(output, L);
|
||||
write(L, image_hex(b"1001000"));
|
||||
writeline(output, L);
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Add further tests here ...
|
||||
----------------------------------------------------------------
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- end of tests
|
||||
----------------------------------------------------------------
|
||||
wait;
|
||||
end process;
|
||||
|
||||
end bench;
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: images_test.vhdl,v $ $Revision: 1.1 $ $Date: 1993/10/25 20:47:12 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for test bench for images package
|
||||
--
|
||||
|
||||
entity images_test is
|
||||
|
||||
end images_test;
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: ir-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 18:56:39 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture of instruction register.
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_instr.all;
|
||||
|
||||
architecture behaviour of ir is
|
||||
|
||||
begin
|
||||
|
||||
reg: process (d, latch_en, immed_sel1, immed_sel2,
|
||||
immed_unsigned1, immed_unsigned2, immed_en1, immed_en2)
|
||||
|
||||
variable latched_instr : dlx_word;
|
||||
|
||||
use work.bv_arithmetic.bv_zext, work.bv_arithmetic.bv_sext;
|
||||
|
||||
begin
|
||||
if latch_en = '1' then
|
||||
latched_instr := d;
|
||||
ir_out <= latched_instr after Tpd;
|
||||
end if;
|
||||
--
|
||||
if immed_en1 = '1' then
|
||||
if immed_sel1 = immed_size_16 then
|
||||
if immed_unsigned1 = '1' then
|
||||
immed_q1 <= bv_zext(latched_instr(16 to 31), 32) after Tpd;
|
||||
else
|
||||
immed_q1 <= bv_sext(latched_instr(16 to 31), 32) after Tpd;
|
||||
end if;
|
||||
else -- immed_sel1 = immed_size_26
|
||||
if immed_unsigned1 = '1' then
|
||||
immed_q1 <= bv_zext(latched_instr(6 to 31), 32) after Tpd;
|
||||
else
|
||||
immed_q1 <= bv_sext(latched_instr(6 to 31), 32) after Tpd;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
immed_q1 <= null after Tpd;
|
||||
end if;
|
||||
--
|
||||
if immed_en2 = '1' then
|
||||
if immed_sel2 = immed_size_16 then
|
||||
if immed_unsigned2 = '1' then
|
||||
immed_q2 <= bv_zext(latched_instr(16 to 31), 32) after Tpd;
|
||||
else
|
||||
immed_q2 <= bv_sext(latched_instr(16 to 31), 32) after Tpd;
|
||||
end if;
|
||||
else -- immed_sel2 = immed_size_26
|
||||
if immed_unsigned2 = '1' then
|
||||
immed_q2 <= bv_zext(latched_instr(6 to 31), 32) after Tpd;
|
||||
else
|
||||
immed_q2 <= bv_sext(latched_instr(6 to 31), 32) after Tpd;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
immed_q2 <= null after Tpd;
|
||||
end if;
|
||||
end process reg;
|
||||
|
||||
end behaviour;
|
||||
@@ -0,0 +1,46 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: ir.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 18:55:16 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for instruction register.
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_types.all,
|
||||
work.dlx_instr.immed_size;
|
||||
|
||||
entity ir is
|
||||
generic (Tpd : Time;
|
||||
tag : string := "";
|
||||
origin_x, origin_y : real := 0.0);
|
||||
port (d : in dlx_word;
|
||||
immed_q1, immed_q2 : out dlx_word_bus bus;
|
||||
ir_out : out dlx_word;
|
||||
latch_en : in bit;
|
||||
immed_sel1, immed_sel2 : in immed_size;
|
||||
immed_unsigned1, immed_unsigned2 : in bit;
|
||||
immed_en1, immed_en2 : in bit);
|
||||
end ir;
|
||||
@@ -0,0 +1,43 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: latch-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 18:59:13 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture of transparent latch.
|
||||
--
|
||||
|
||||
|
||||
architecture behaviour of latch is
|
||||
|
||||
begin
|
||||
|
||||
process (d, latch_en)
|
||||
begin
|
||||
if latch_en = '1' then
|
||||
q <= d after Tpd;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end behaviour;
|
||||
@@ -0,0 +1,41 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: latch.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 18:58:13 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for transparent latch.
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_types.all;
|
||||
|
||||
entity latch is
|
||||
generic (Tpd : Time;
|
||||
tag : string := "";
|
||||
origin_x, origin_y : real := 0.0);
|
||||
port (d : in dlx_word;
|
||||
q : out dlx_word;
|
||||
latch_en : in bit);
|
||||
end latch;
|
||||
@@ -0,0 +1,36 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: mem_types.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 20:39:06 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Types package for memory model
|
||||
--
|
||||
|
||||
|
||||
package mem_types is
|
||||
|
||||
type mem_width is (width_byte, width_halfword, width_word);
|
||||
|
||||
end mem_types;
|
||||
@@ -0,0 +1,226 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: memory-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 21:09:45 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture for memory model
|
||||
--
|
||||
|
||||
|
||||
use work.bv_arithmetic.bv_to_natural,
|
||||
work.bv_arithmetic.natural_to_bv,
|
||||
work.images.image_hex,
|
||||
std.textio.all;
|
||||
|
||||
|
||||
architecture behaviour of memory is
|
||||
|
||||
begin
|
||||
|
||||
mem : process
|
||||
|
||||
constant low_address : natural := 0;
|
||||
constant high_address : natural := mem_size - 1;
|
||||
|
||||
subtype byte is bit_vector(0 to 7);
|
||||
subtype ls_2_bits is bit_vector(1 downto 0);
|
||||
|
||||
type memory_array is
|
||||
array (natural range low_address to high_address) of byte;
|
||||
|
||||
variable mem : memory_array;
|
||||
variable aligned_a : dlx_address;
|
||||
variable address : natural;
|
||||
|
||||
variable L : line;
|
||||
|
||||
|
||||
procedure load(mem : out memory_array) is
|
||||
|
||||
file binary_file : text is in "dlx.out";
|
||||
variable L : line;
|
||||
variable addr : natural;
|
||||
variable word : dlx_word;
|
||||
|
||||
procedure read_hex_natural(L : inout line; addr : out natural) is
|
||||
variable result : natural := 0;
|
||||
variable ch : character;
|
||||
begin
|
||||
for i in 1 to 8 loop
|
||||
read(L, ch);
|
||||
if ('0' <= ch and ch <= '9') then
|
||||
result := result*16 + character'pos(ch) - character'pos('0');
|
||||
else
|
||||
result := result*16 + character'pos(ch) - character'pos('a') + 10;
|
||||
end if;
|
||||
end loop;
|
||||
addr := result;
|
||||
end read_hex_natural;
|
||||
|
||||
procedure read_hex_word(L : inout line; word : out dlx_word) is
|
||||
variable result : dlx_word;
|
||||
variable digit, r : natural := 0;
|
||||
variable ch : character;
|
||||
begin
|
||||
read(L, ch); -- the space between addr and data
|
||||
for i in 10 to 17 loop
|
||||
read(L, ch);
|
||||
if ('0' <= ch and ch <= '9') then
|
||||
digit := character'pos(ch) - character'pos('0');
|
||||
else
|
||||
digit := character'pos(ch) - character'pos('a') + 10;
|
||||
end if;
|
||||
result(r to r+3) := natural_to_bv(digit, 4);
|
||||
r := r + 4;
|
||||
end loop;
|
||||
word := result;
|
||||
end read_hex_word;
|
||||
|
||||
begin
|
||||
while not endfile(binary_file) loop
|
||||
readline(binary_file, L);
|
||||
read_hex_natural(L, addr);
|
||||
read_hex_word(L, word);
|
||||
--
|
||||
write(L, addr);
|
||||
write(L, ' ');
|
||||
write(L, image_hex(word));
|
||||
writeline(output, L);
|
||||
--
|
||||
mem(addr) := word(0 to 7);
|
||||
mem(addr+1) := word(8 to 15);
|
||||
mem(addr+2) := word(16 to 23);
|
||||
mem(addr+3) := word(24 to 31);
|
||||
end loop;
|
||||
end load;
|
||||
|
||||
|
||||
procedure do_write is
|
||||
begin
|
||||
--
|
||||
-- align address to accessed unit
|
||||
--
|
||||
aligned_a := a;
|
||||
case width is
|
||||
when width_word =>
|
||||
aligned_a(1 downto 0) := b"00";
|
||||
when width_halfword =>
|
||||
aligned_a(0) := '0';
|
||||
when width_byte =>
|
||||
null;
|
||||
end case;
|
||||
address := bv_to_natural(aligned_a);
|
||||
case width is
|
||||
when width_word =>
|
||||
mem(address) := d(0 to 7);
|
||||
mem(address+1) := d(8 to 15);
|
||||
mem(address+2) := d(16 to 23);
|
||||
mem(address+3) := d(24 to 31);
|
||||
when width_halfword =>
|
||||
if a(1) = '0' then -- ms half word
|
||||
mem(address) := d(0 to 7);
|
||||
mem(address+1) := d(8 to 15);
|
||||
else -- ls half word
|
||||
mem(address) := d(16 to 23);
|
||||
mem(address+1) := d(24 to 31);
|
||||
end if;
|
||||
when width_byte =>
|
||||
case ls_2_bits'(a(1 downto 0)) is
|
||||
when b"00" =>
|
||||
mem(address) := d(0 to 7);
|
||||
when b"01" =>
|
||||
mem(address) := d(8 to 15);
|
||||
when b"10" =>
|
||||
mem(address) := d(16 to 23);
|
||||
when b"11" =>
|
||||
mem(address) := d(24 to 31);
|
||||
end case;
|
||||
end case;
|
||||
end do_write;
|
||||
|
||||
procedure do_read is
|
||||
begin
|
||||
aligned_a := a;
|
||||
aligned_a(1 downto 0) := b"00";
|
||||
address := bv_to_natural(aligned_a);
|
||||
d <= mem(address) & mem(address+1) & mem(address+2) & mem(address+3);
|
||||
end do_read;
|
||||
|
||||
|
||||
begin
|
||||
load(mem);
|
||||
-- initialize outputs
|
||||
--
|
||||
d <= null;
|
||||
ready <= '0';
|
||||
--
|
||||
-- process memory cycles
|
||||
--
|
||||
loop
|
||||
--
|
||||
-- wait for a command, valid on leading edge of phi2
|
||||
--
|
||||
wait until phi2 = '1' and mem_enable = '1';
|
||||
--
|
||||
-- decode address and perform command if selected
|
||||
--
|
||||
address := bv_to_natural(a);
|
||||
if address >= low_address and address <= high_address then
|
||||
if write_enable = '1' then -- write cycle
|
||||
do_write;
|
||||
wait for Tac1; -- write access time, 1st cycle
|
||||
else -- read cycle
|
||||
wait for Tac1; -- read access time, 1st cycle
|
||||
do_read;
|
||||
end if;
|
||||
-- ready synchronous with phi2
|
||||
wait until phi2 = '1';
|
||||
ready <= '1' after Tpd_clk_out;
|
||||
wait until phi2 = '0';
|
||||
ready <= '0' after Tpd_clk_out;
|
||||
-- do subsequent cycles in burst
|
||||
while burst = '1' loop
|
||||
wait until phi2 = '1';
|
||||
if write_enable = '1' then -- write cycle
|
||||
do_write;
|
||||
wait for Tacb; -- write access time, burst cycle
|
||||
else -- read cycle
|
||||
wait for Tacb; -- read access time, burst cycle
|
||||
do_read;
|
||||
end if;
|
||||
-- ready synchronous with phi2
|
||||
wait until phi2 = '1';
|
||||
ready <= '1' after Tpd_clk_out;
|
||||
wait until phi2 = '0';
|
||||
ready <= '0' after Tpd_clk_out;
|
||||
end loop;
|
||||
if write_enable = '0' then -- was read
|
||||
d <= null after Tpd_clk_out;
|
||||
end if;
|
||||
end if;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
end behaviour;
|
||||
@@ -0,0 +1,54 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: memory.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 21:09:12 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for memory model
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_types.all, work.mem_types.all;
|
||||
|
||||
entity memory is
|
||||
|
||||
generic (mem_size : positive; -- size in bytes (multiple of 4)
|
||||
Tac1 : Time; -- access time 1st cycle (read or write)
|
||||
Tacb : Time; -- access time burst (read or write)
|
||||
Tpd_clk_out : Time; -- clock to output delay
|
||||
tag : string := "";
|
||||
origin_x, origin_y : real := 0.0);
|
||||
|
||||
port (phi1, phi2 : in bit; -- 2-phase non-overlapping clocks
|
||||
a : in dlx_address; -- byte address: a(0) is lsb
|
||||
d : inout dlx_word_bus bus; -- bidirectional data bus: d(0) is msb
|
||||
width : in mem_width; -- byte/haldword/word indicator
|
||||
write_enable : in bit; -- selects read or write cycle
|
||||
burst : in bit := '0'; -- indicates more to come in burst
|
||||
-- can be left open
|
||||
-- for non-burst client
|
||||
mem_enable : in bit; -- starts memory cycle
|
||||
ready : out bit); -- status from memory system
|
||||
|
||||
end memory;
|
||||
@@ -0,0 +1,330 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: memory_test-bench.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 21:10:12 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Architecture for test bench for behavioural architecture of memory
|
||||
--
|
||||
|
||||
|
||||
use std.textio.all,
|
||||
work.dlx_types.all,
|
||||
work.mem_types.all,
|
||||
work.bv_arithmetic.bv_addu,
|
||||
work.images.image_hex;
|
||||
|
||||
architecture bench of memory_test is
|
||||
|
||||
component clock_gen
|
||||
port (phi1, phi2 : out bit;
|
||||
reset : out bit);
|
||||
end component;
|
||||
|
||||
component memory
|
||||
port (phi1, phi2 : in bit;
|
||||
a : in dlx_address;
|
||||
d : inout dlx_word_bus bus;
|
||||
width : in mem_width;
|
||||
write_enable : in bit;
|
||||
burst : in bit;
|
||||
mem_enable : in bit;
|
||||
ready : out bit);
|
||||
end component;
|
||||
|
||||
for cg : clock_gen
|
||||
use entity work.clock_gen(behaviour)
|
||||
generic map (Tpw => 8 ns, Tps => 2 ns);
|
||||
|
||||
for mem : memory
|
||||
use entity work.memory(behaviour)
|
||||
generic map (mem_size => 65536,
|
||||
Tac1 => 95 ns, Tacb => 15 ns, Tpd_clk_out => 2 ns);
|
||||
|
||||
signal phi1, phi2, reset : bit;
|
||||
signal a : dlx_address;
|
||||
signal d : dlx_word_bus bus;
|
||||
signal width : mem_width;
|
||||
signal write_enable, mem_enable, burst, ifetch, ready : bit;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
cg : clock_gen
|
||||
port map (phi1, phi2, reset);
|
||||
|
||||
mem : memory
|
||||
port map (phi1, phi2, a, d, width, write_enable, burst, mem_enable, ready);
|
||||
|
||||
test: process
|
||||
|
||||
variable data_word : dlx_word;
|
||||
variable L : line;
|
||||
VARIABLE blk : dlx_word_array(1 to 4);
|
||||
|
||||
procedure write (address : in dlx_address;
|
||||
data_width : in mem_width;
|
||||
data : in dlx_word;
|
||||
Tpd_clk_out : in time -- clock to output delay
|
||||
) is
|
||||
|
||||
begin -- write
|
||||
wait until phi1 = '1';
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
a <= address after Tpd_clk_out;
|
||||
width <= data_width after Tpd_clk_out;
|
||||
d <= data after Tpd_clk_out;
|
||||
write_enable <= '1' after Tpd_clk_out;
|
||||
burst <= '0' after Tpd_Clk_Out;
|
||||
mem_enable <= '1' after Tpd_clk_out;
|
||||
ifetch <= '0' after Tpd_clk_out;
|
||||
loop
|
||||
wait until phi2 = '0';
|
||||
exit when ready = '1' or reset = '1';
|
||||
end loop;
|
||||
d <= null after Tpd_clk_out;
|
||||
write_enable <= '0' after Tpd_clk_out;
|
||||
mem_enable <= '0' after Tpd_clk_out;
|
||||
end write;
|
||||
|
||||
|
||||
procedure read (address : in dlx_address;
|
||||
data_width : in mem_width;
|
||||
instr_fetch : in boolean;
|
||||
data : out dlx_word;
|
||||
Tpd_clk_out : in time -- clock to output delay
|
||||
) is
|
||||
|
||||
begin -- read
|
||||
wait until phi1 = '1';
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
a <= address after Tpd_clk_out;
|
||||
width <= data_width after Tpd_clk_out;
|
||||
write_enable <= '0' after Tpd_clk_out;
|
||||
burst <= '0' after Tpd_Clk_Out;
|
||||
mem_enable <= '1' after Tpd_clk_out;
|
||||
ifetch <= bit'val(boolean'pos(instr_fetch)) after Tpd_clk_out;
|
||||
loop
|
||||
wait until phi2 = '0';
|
||||
exit when ready = '1' or reset = '1';
|
||||
end loop;
|
||||
data := d;
|
||||
mem_enable <= '0' after Tpd_clk_out;
|
||||
end read;
|
||||
|
||||
|
||||
procedure write_burst (address : in dlx_address;
|
||||
data : in dlx_word_array;
|
||||
Tpd_clk_out : in time -- clock to output delay
|
||||
) is
|
||||
VARIABLE next_address : dlx_address := address;
|
||||
VARIABLE ignore_overflow : boolean;
|
||||
VARIABLE index : natural;
|
||||
begin -- write_burst
|
||||
wait until phi1 = '1';
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
width <= width_word after Tpd_clk_out;
|
||||
write_enable <= '1' after Tpd_clk_out;
|
||||
mem_enable <= '1' after Tpd_clk_out;
|
||||
ifetch <= '0' after Tpd_clk_out;
|
||||
burst <= '1' after Tpd_Clk_Out;
|
||||
index := data'left;
|
||||
burst_loop : LOOP
|
||||
IF (index = data'right) THEN
|
||||
burst <= '0' after Tpd_Clk_Out;
|
||||
END IF;
|
||||
a <= next_address after Tpd_clk_out;
|
||||
d <= data(index) after Tpd_clk_out;
|
||||
wait_loop : LOOP
|
||||
WAIT UNTIL phi2 = '0';
|
||||
EXIT burst_loop WHEN reset = '1' OR (ready = '1' AND index = data'right);
|
||||
EXIT wait_loop WHEN ready = '1';
|
||||
END LOOP wait_loop;
|
||||
index := index + 1;
|
||||
bv_addu(next_address, X"00000004", next_address, ignore_overflow);
|
||||
END LOOP burst_loop;
|
||||
d <= null after Tpd_clk_out;
|
||||
write_enable <= '0' after Tpd_clk_out;
|
||||
mem_enable <= '0' after Tpd_clk_out;
|
||||
end write_burst;
|
||||
|
||||
|
||||
procedure read_burst (address : in dlx_address;
|
||||
data : out dlx_word_array;
|
||||
Tpd_clk_out : in time -- clock to output delay
|
||||
) is
|
||||
VARIABLE next_address : dlx_address := address;
|
||||
VARIABLE ignore_overflow : boolean;
|
||||
VARIABLE index : natural;
|
||||
begin -- read_burst
|
||||
wait until phi1 = '1';
|
||||
if reset = '1' then
|
||||
return;
|
||||
end if;
|
||||
width <= width_word after Tpd_clk_out;
|
||||
write_enable <= '0' after Tpd_clk_out;
|
||||
mem_enable <= '1' after Tpd_clk_out;
|
||||
ifetch <= '0' after Tpd_clk_out;
|
||||
burst <= '1' after Tpd_Clk_Out;
|
||||
index := data'left;
|
||||
burst_loop : LOOP
|
||||
IF (index = data'right) THEN
|
||||
burst <= '0' after Tpd_Clk_Out;
|
||||
END IF;
|
||||
a <= next_address after Tpd_clk_out;
|
||||
wait_loop : LOOP
|
||||
WAIT UNTIL phi2 = '0';
|
||||
data(index) := d;
|
||||
EXIT burst_loop WHEN reset = '1' OR (ready = '1' AND index = data'right);
|
||||
EXIT wait_loop WHEN ready = '1';
|
||||
END LOOP wait_loop;
|
||||
index := index + 1;
|
||||
bv_addu(next_address, X"00000004", next_address, ignore_overflow);
|
||||
END LOOP burst_loop;
|
||||
mem_enable <= '0' after Tpd_clk_out;
|
||||
end read_burst;
|
||||
|
||||
|
||||
begin
|
||||
wait until reset = '0';
|
||||
write(L, string'("Write word X""00000004"" to 4:"));
|
||||
writeline(output, L);
|
||||
write(X"0000_0004", width_word, X"00000004", 2 ns);
|
||||
--
|
||||
write(L, string'("Read word from X""00000004"":"));
|
||||
writeline(output, L);
|
||||
data_word := X"0000_0000";
|
||||
read(X"0000_0004", width_word, false, data_word, 2 ns);
|
||||
write(L, string'(" result:"));
|
||||
write(L, image_hex(data_word));
|
||||
writeline(output, L);
|
||||
--
|
||||
write(L, string'("Write halfword X""2222"" to 0:"));
|
||||
writeline(output, L);
|
||||
write(X"0000_0000", width_halfword, X"2222_0000", 2 ns);
|
||||
--
|
||||
write(L, string'("Write halfword X""3333"" to 2:"));
|
||||
writeline(output, L);
|
||||
write(X"0000_0002", width_halfword, X"0000_3333", 2 ns);
|
||||
--
|
||||
write(L, string'("Read word from X""00000000"":"));
|
||||
writeline(output, L);
|
||||
data_word := X"0000_0000";
|
||||
read(X"0000_0000", width_word, false, data_word, 2 ns);
|
||||
write(L, string'(" result:"));
|
||||
write(L, image_hex(data_word));
|
||||
writeline(output, L);
|
||||
--
|
||||
write(L, string'("Read halfword from X""00000003"":"));
|
||||
writeline(output, L);
|
||||
data_word := X"0000_0000";
|
||||
read(X"0000_0003", width_halfword, false, data_word, 2 ns);
|
||||
write(L, string'(" result:"));
|
||||
write(L, image_hex(data_word));
|
||||
writeline(output, L);
|
||||
--
|
||||
write(L, string'("Write bytes X""44"" to 4, X""55"" to 5, X""66"" to 6, X""77"" to 7:"));
|
||||
writeline(output, L);
|
||||
write(X"0000_0004", width_byte, X"44_00_00_00", 2 ns);
|
||||
write(X"0000_0005", width_byte, X"00_55_00_00", 2 ns);
|
||||
write(X"0000_0006", width_byte, X"00_00_66_00", 2 ns);
|
||||
write(X"0000_0007", width_byte, X"00_00_00_77", 2 ns);
|
||||
--
|
||||
write(L, string'("Read word from X""00000004"":"));
|
||||
writeline(output, L);
|
||||
data_word := X"0000_0000";
|
||||
read(X"0000_0004", width_word, false, data_word, 2 ns);
|
||||
write(L, string'(" result:"));
|
||||
write(L, image_hex(data_word));
|
||||
writeline(output, L);
|
||||
--
|
||||
write(L, string'("Read byte from X""00000004"":"));
|
||||
writeline(output, L);
|
||||
data_word := X"0000_0000";
|
||||
read(X"0000_0004", width_byte, false, data_word, 2 ns);
|
||||
write(L, string'(" result:"));
|
||||
write(L, image_hex(data_word));
|
||||
writeline(output, L);
|
||||
--
|
||||
write(L, string'("Read byte from X""00000005"":"));
|
||||
writeline(output, L);
|
||||
data_word := X"0000_0000";
|
||||
read(X"0000_0005", width_byte, false, data_word, 2 ns);
|
||||
write(L, string'(" result:"));
|
||||
write(L, image_hex(data_word));
|
||||
writeline(output, L);
|
||||
--
|
||||
write(L, string'("Read byte from X""00000006"":"));
|
||||
writeline(output, L);
|
||||
data_word := X"0000_0000";
|
||||
read(X"0000_0006", width_byte, false, data_word, 2 ns);
|
||||
write(L, string'(" result:"));
|
||||
write(L, image_hex(data_word));
|
||||
writeline(output, L);
|
||||
--
|
||||
write(L, string'("Read byte from X""00000007"":"));
|
||||
writeline(output, L);
|
||||
data_word := X"0000_0000";
|
||||
read(X"0000_0007", width_byte, false, data_word, 2 ns);
|
||||
write(L, string'(" result:"));
|
||||
write(L, image_hex(data_word));
|
||||
writeline(output, L);
|
||||
--
|
||||
write(L, string'("Write burst to 8..11:"));
|
||||
writeline(output, L);
|
||||
blk := (X"88888888", X"99999999", X"AAAAAAAA", X"BBBBBBBB");
|
||||
write_burst(X"0000_0008", blk, 2 ns);
|
||||
--
|
||||
write(L, string'("Read burst from 8..11:"));
|
||||
writeline(output, L);
|
||||
blk := (OTHERS => X"0000_0000");
|
||||
read_burst(X"0000_0008", blk, 2 ns);
|
||||
write(L, string'(" result: ("));
|
||||
FOR i IN blk'range LOOP
|
||||
write(L, image_hex(blk(i)));
|
||||
IF (i /= blk'right) THEN
|
||||
write(L, string'(", "));
|
||||
END IF;
|
||||
END LOOP; -- i
|
||||
write(L, ')');
|
||||
writeline(output, L);
|
||||
--
|
||||
-- This should hang
|
||||
write(L, string'("Read word from X""00100000"":"));
|
||||
writeline(output, L);
|
||||
data_word := X"0000_0000";
|
||||
read(X"0010_0000", width_word, false, data_word, 2 ns);
|
||||
write(L, string'(" result:"));
|
||||
write(L, data_word);
|
||||
writeline(output, L);
|
||||
--
|
||||
end process test;
|
||||
|
||||
end bench;
|
||||
@@ -0,0 +1,33 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: memory_test.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 21:10:02 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for test bench for memory
|
||||
--
|
||||
|
||||
|
||||
entity memory_test is
|
||||
end memory_test;
|
||||
@@ -0,0 +1,158 @@
|
||||
images.vhdl
|
||||
Package specification for images.
|
||||
images-body.vhdl
|
||||
Package body for images.
|
||||
images_test.vhdl
|
||||
Entity declaration for test bench for images package.
|
||||
images_test-bench.vhdl
|
||||
Architecture body for test bench for images package.
|
||||
|
||||
bv_arithmetic.vhdl
|
||||
Package specification for bit vector conversions and arithmetic
|
||||
bv_arithmetic-body.vhdl
|
||||
Package body for bit vector conversions and arithmetic
|
||||
bv_test.vhdl
|
||||
Entity declaration for test bench for bit vector arithmetic package
|
||||
bv_test-bench.vhdl
|
||||
Architecture for test bench for bit vector arithmetic package
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
clock_gen.vhdl
|
||||
Entity declaration for clock generator
|
||||
clock_gen-behaviour.vhdl
|
||||
Behavioural architecture body for clock generator
|
||||
clock_gen_test.vhdl
|
||||
Entity declaration for test bench for clock generator
|
||||
clock_gen_test-bench.vhdl
|
||||
Architecture for test bench for clock generator
|
||||
|
||||
dlx_types.vhdl
|
||||
Package specification for types used in dlx model
|
||||
dlx_types-body.vhdl
|
||||
Package body for types used in dlx model
|
||||
|
||||
mem_types.vhdl
|
||||
Types package for memory model
|
||||
|
||||
memory.vhdl
|
||||
Entity declaration for memory model
|
||||
memory-behaviour.vhdl
|
||||
Behavioural architecture for memory model
|
||||
memory_test.vhdl
|
||||
Entity declaration for test bench for memory
|
||||
memory_test-bench.vhdl
|
||||
Architecture for test bench for behavioural architecture of memory
|
||||
|
||||
dlx_instr.vhdl
|
||||
Package specification for DLX instructions
|
||||
dlx_instr-body.vhdl
|
||||
Package body for DLX instructions
|
||||
|
||||
dlx_bus_monitor.vhdl
|
||||
Entity declaration of DLX bus monitor
|
||||
dlx_bus_monitor-behaviour.vhdl
|
||||
Behavioural architecture of DLX bus monitor
|
||||
|
||||
dlx_test.vhdl
|
||||
Entity declaration for test bench for DLX
|
||||
dlx_test-bench.vhdl
|
||||
Architecture for test bench for DLX,
|
||||
consisting of clock generator, memory and bus_monitor
|
||||
|
||||
dlx.vhdl
|
||||
Entity specification for DLX processor
|
||||
|
||||
dlx-behaviour.vhdl
|
||||
Behavioural architecture for DLX processor
|
||||
dlx_test_behaviour.vhdl
|
||||
Configuration of test bench for DLX, using architecture behaviour
|
||||
|
||||
dlx-instrumented.vhdl
|
||||
Instrumented behavioural architecture for DLX, that generates
|
||||
a files of instruction execution frequencies for a program.
|
||||
dlx_test_instrumented.vhdl
|
||||
Configuration of test bench for DLX, using instrumented
|
||||
architecture of CPU and empty architecture of bus monitor.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
alu_types.vhdl
|
||||
Package defining types for ALU.
|
||||
alu.vhdl
|
||||
Entity declaration for ALU.
|
||||
alu-behaviour.vhdl
|
||||
Behavioural architecture of ALU.
|
||||
|
||||
ir.vhdl
|
||||
Entity declaration for instruction register.
|
||||
ir-behaviour.vhdl
|
||||
Behavioural architecture of instruction register.
|
||||
|
||||
latch.vhdl
|
||||
Entity declaration for transparent latch.
|
||||
latch-behaviour.vhdl
|
||||
Behavioural architecture of transparent latch.
|
||||
|
||||
mux2.vhdl
|
||||
Entity declaration for two-input multiplexor.
|
||||
mux2-behaviour.vhdl
|
||||
Behavioural architecture of two-input multiplexor.
|
||||
|
||||
reg_1_out.vhdl
|
||||
Entity declaration for register with one tri-state output.
|
||||
reg_1_out-behaviour.vhdl
|
||||
Behavioural architecture of register with one tri-state output.
|
||||
|
||||
reg_2_1_out.vhdl
|
||||
Entity declaration for register with two tri-state outputs and
|
||||
one ordinary output.
|
||||
reg_2_1_out-behaviour.vhdl
|
||||
Behavioural architecture of register with two tri-state
|
||||
outputs and one ordinary output.
|
||||
|
||||
reg_2_out.vhdl
|
||||
Entity declaration for register with two tri-state outputs.
|
||||
reg_2_out-behaviour.vhdl
|
||||
Behavioural architecture of register with two tri-state outputs.
|
||||
|
||||
reg_3_out.vhdl
|
||||
Entity declaration for register with three tri-state outputs.
|
||||
reg_3_out-behaviour.vhdl
|
||||
Behavioural architecture of register with three tri-state outputs.
|
||||
|
||||
reg_file.vhdl
|
||||
Entity declaration for register file.
|
||||
reg_file-behaviour.vhdl
|
||||
Behavioural architecture of register file.
|
||||
|
||||
controller.vhdl
|
||||
Entity declaration for DLX control section.
|
||||
controller-behaviour.vhdl
|
||||
Behavioural architecture of DLX control section.
|
||||
|
||||
dlx-rtl.vhdl
|
||||
Register transfer level architecture of DLX processor.
|
||||
|
||||
dlx_test_rtl.vhdl
|
||||
Configuration of DLX test bench using register transfer level
|
||||
architecture of DLX processor.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
cache_types.vhdl
|
||||
Package spec defining types for cache.
|
||||
cache.vhdl
|
||||
Entity declaration for cache.
|
||||
cache-behaviour.vhdl
|
||||
Behavioural architecture for cache.
|
||||
|
||||
dlx_test-bench_cache.vhdl
|
||||
Architecture for test bench for DLX and cache,
|
||||
including clock generator, memory and bus monitors for
|
||||
both CPU/cache and cache/memory buses.
|
||||
|
||||
dlx_test_cache.vhdl
|
||||
Configuration of test bench for DLX and cache,
|
||||
using behavioural architectures.
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: mux2-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 19:02:04 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture of two-input multiplexor.
|
||||
--
|
||||
|
||||
|
||||
architecture behaviour of mux2 is
|
||||
begin
|
||||
with sel select
|
||||
y <= i0 after Tpd when '0',
|
||||
i1 after Tpd when '1';
|
||||
end behaviour;
|
||||
@@ -0,0 +1,41 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: mux2.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 19:01:03 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for two-input multiplexor.
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_types.all;
|
||||
|
||||
entity mux2 is
|
||||
generic (Tpd : Time;
|
||||
tag : string := "";
|
||||
origin_x, origin_y : real := 0.0);
|
||||
port (i0, i1 : in dlx_word;
|
||||
y : out dlx_word;
|
||||
sel : in bit);
|
||||
end mux2;
|
||||
@@ -0,0 +1,51 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: reg_1_out-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 19:04:21 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture of register with one tri-state output.
|
||||
--
|
||||
|
||||
|
||||
architecture behaviour of reg_1_out is
|
||||
|
||||
begin
|
||||
|
||||
reg: process (d, latch_en, out_en)
|
||||
|
||||
variable latched_value : dlx_word;
|
||||
|
||||
begin
|
||||
if latch_en = '1' then
|
||||
latched_value := d;
|
||||
end if;
|
||||
if out_en = '1' then
|
||||
q <= latched_value after Tpd;
|
||||
else
|
||||
q <= null after Tpd;
|
||||
end if;
|
||||
end process reg;
|
||||
|
||||
end behaviour;
|
||||
@@ -0,0 +1,42 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: reg_1_out.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 19:04:11 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for register with one tri-state output.
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_types.all;
|
||||
|
||||
entity reg_1_out is
|
||||
generic (Tpd : Time;
|
||||
tag : string := "";
|
||||
origin_x, origin_y : real := 0.0);
|
||||
port (d : in dlx_word;
|
||||
q : out dlx_word_bus bus;
|
||||
latch_en : in bit;
|
||||
out_en : in bit);
|
||||
end reg_1_out;
|
||||
@@ -0,0 +1,58 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: reg_2_1_out-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 19:06:59 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture of register with two tri-state
|
||||
-- outputs and one ordinary output.
|
||||
--
|
||||
|
||||
|
||||
architecture behaviour of reg_2_1_out is
|
||||
|
||||
begin
|
||||
|
||||
reg: process (d, latch_en, out_en1, out_en2)
|
||||
|
||||
variable latched_value : dlx_word;
|
||||
|
||||
begin
|
||||
if latch_en = '1' then
|
||||
latched_value := d;
|
||||
end if;
|
||||
if out_en1 = '1' then
|
||||
q1 <= latched_value after Tpd;
|
||||
else
|
||||
q1 <= null after Tpd;
|
||||
end if;
|
||||
if out_en2 = '1' then
|
||||
q2 <= latched_value after Tpd;
|
||||
else
|
||||
q2 <= null after Tpd;
|
||||
end if;
|
||||
q3 <= latched_value after Tpd;
|
||||
end process reg;
|
||||
|
||||
end behaviour;
|
||||
@@ -0,0 +1,44 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: reg_2_1_out.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 19:06:47 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for register with two tri-state outputs and
|
||||
-- one ordinary output.
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_types.all;
|
||||
|
||||
entity reg_2_1_out is
|
||||
generic (Tpd : Time;
|
||||
tag : string := "";
|
||||
origin_x, origin_y : real := 0.0);
|
||||
port (d : in dlx_word;
|
||||
q1, q2 : out dlx_word_bus bus;
|
||||
q3 : out dlx_word;
|
||||
latch_en : in bit;
|
||||
out_en1, out_en2 : in bit);
|
||||
end reg_2_1_out;
|
||||
@@ -0,0 +1,56 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: reg_2_out-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 19:09:21 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture of register with two tri-state outputs.
|
||||
--
|
||||
|
||||
|
||||
architecture behaviour of reg_2_out is
|
||||
|
||||
begin
|
||||
|
||||
reg: process (d, latch_en, out_en1, out_en2)
|
||||
|
||||
variable latched_value : dlx_word;
|
||||
|
||||
begin
|
||||
if latch_en = '1' then
|
||||
latched_value := d;
|
||||
end if;
|
||||
if out_en1 = '1' then
|
||||
q1 <= latched_value after Tpd;
|
||||
else
|
||||
q1 <= null after Tpd;
|
||||
end if;
|
||||
if out_en2 = '1' then
|
||||
q2 <= latched_value after Tpd;
|
||||
else
|
||||
q2 <= null after Tpd;
|
||||
end if;
|
||||
end process reg;
|
||||
|
||||
end behaviour;
|
||||
@@ -0,0 +1,42 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: reg_2_out.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 19:09:13 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for register with two tri-state outputs.
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_types.all;
|
||||
|
||||
entity reg_2_out is
|
||||
generic (Tpd : Time;
|
||||
tag : string := "";
|
||||
origin_x, origin_y : real := 0.0);
|
||||
port (d : in dlx_word;
|
||||
q1, q2 : out dlx_word_bus bus;
|
||||
latch_en : in bit;
|
||||
out_en1, out_en2 : in bit);
|
||||
end reg_2_out;
|
||||
@@ -0,0 +1,61 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: reg_3_out-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 19:14:21 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture of register with three tri-state outputs.
|
||||
--
|
||||
|
||||
|
||||
architecture behaviour of reg_3_out is
|
||||
|
||||
begin
|
||||
|
||||
reg: process (d, latch_en, out_en1, out_en2, out_en3)
|
||||
|
||||
variable latched_value : dlx_word;
|
||||
|
||||
begin
|
||||
if latch_en = '1' then
|
||||
latched_value := d;
|
||||
end if;
|
||||
if out_en1 = '1' then
|
||||
q1 <= latched_value after Tpd;
|
||||
else
|
||||
q1 <= null after Tpd;
|
||||
end if;
|
||||
if out_en2 = '1' then
|
||||
q2 <= latched_value after Tpd;
|
||||
else
|
||||
q2 <= null after Tpd;
|
||||
end if;
|
||||
if out_en3 = '1' then
|
||||
q3 <= latched_value after Tpd;
|
||||
else
|
||||
q3 <= null after Tpd;
|
||||
end if;
|
||||
end process reg;
|
||||
|
||||
end behaviour;
|
||||
@@ -0,0 +1,42 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: reg_3_out.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 19:14:00 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for register with three tri-state outputs.
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_types.all;
|
||||
|
||||
entity reg_3_out is
|
||||
generic (Tpd : Time;
|
||||
tag : string := "";
|
||||
origin_x, origin_y : real := 0.0);
|
||||
port (d : in dlx_word;
|
||||
q1, q2, q3 : out dlx_word_bus bus;
|
||||
latch_en : in bit;
|
||||
out_en1, out_en2, out_en3 : in bit);
|
||||
end reg_3_out;
|
||||
@@ -0,0 +1,76 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: reg_file-behaviour.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 19:16:52 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Behavioural architecture of register file.
|
||||
--
|
||||
|
||||
|
||||
architecture behaviour of reg_file is
|
||||
|
||||
begin
|
||||
|
||||
reg: process (a1, a2, a3, d3, write_en)
|
||||
|
||||
use work.bv_arithmetic.bv_to_natural;
|
||||
|
||||
constant all_zeros : dlx_word := X"0000_0000";
|
||||
|
||||
type register_array is array (reg_index range 1 to 31) of dlx_word;
|
||||
|
||||
variable register_file : register_array;
|
||||
variable reg_index1, reg_index2, reg_index3 : reg_index;
|
||||
|
||||
begin
|
||||
-- do write first if enabled
|
||||
--
|
||||
if write_en = '1' then
|
||||
reg_index3 := bv_to_natural(a3);
|
||||
if reg_index3 /= 0 then
|
||||
register_file(reg_index3) := d3;
|
||||
end if;
|
||||
end if;
|
||||
--
|
||||
-- read port 1
|
||||
--
|
||||
reg_index1 := bv_to_natural(a1);
|
||||
if reg_index1 /= 0 then
|
||||
q1 <= register_file(reg_index1) after Tac;
|
||||
else
|
||||
q1 <= all_zeros after Tac;
|
||||
end if;
|
||||
--
|
||||
-- read port 2
|
||||
--
|
||||
reg_index2 := bv_to_natural(a2);
|
||||
if reg_index2 /= 0 then
|
||||
q2 <= register_file(reg_index2) after Tac;
|
||||
else
|
||||
q2 <= all_zeros after Tac;
|
||||
end if;
|
||||
end process reg;
|
||||
|
||||
end behaviour;
|
||||
@@ -0,0 +1,46 @@
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 1993, Peter J. Ashenden
|
||||
-- Mail: Dept. Computer Science
|
||||
-- University of Adelaide, SA 5005, Australia
|
||||
-- e-mail: petera@cs.adelaide.edu.au
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 1, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- $RCSfile: reg_file.vhdl,v $ $Revision: 2.1 $ $Date: 1993/11/02 19:16:43 $
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
--
|
||||
-- Entity declaration for register file.
|
||||
--
|
||||
|
||||
|
||||
use work.dlx_types.all,
|
||||
work.dlx_instr.all;
|
||||
|
||||
entity reg_file is
|
||||
generic (Tac : Time;
|
||||
tag : string := "";
|
||||
origin_x, origin_y : real := 0.0);
|
||||
port (a1 : in dlx_reg_addr;
|
||||
q1 : out dlx_word;
|
||||
a2 : in dlx_reg_addr;
|
||||
q2 : out dlx_word;
|
||||
a3 : in dlx_reg_addr;
|
||||
d3 : in dlx_word;
|
||||
write_en : in bit);
|
||||
end reg_file;
|
||||
@@ -0,0 +1,2 @@
|
||||
00000000 20020000
|
||||
00000004 44000000
|
||||
@@ -0,0 +1,3 @@
|
||||
.text 0
|
||||
addi r2, r0, 0 ; r2 := 0
|
||||
trap 0
|
||||
@@ -0,0 +1,6 @@
|
||||
00000000 20020000
|
||||
00000004 ac020018
|
||||
00000008 20420001
|
||||
0000000c 6441000a
|
||||
00000010 1420fff0
|
||||
00000014 44000000
|
||||
@@ -0,0 +1,10 @@
|
||||
.text 0
|
||||
addi r2, r0, 0 ; r2 := 0
|
||||
loop:
|
||||
sw counter(r0), r2 ; counter := r2
|
||||
addi r2, r2, 1 ; increment r2
|
||||
snei r1, r2, 10 ; if r2 = 10 then
|
||||
bnez r1, loop ; next loop
|
||||
trap 0
|
||||
counter:
|
||||
.word 0
|
||||
@@ -0,0 +1,5 @@
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/dlx_types.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/dlx_instr.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/alu_types.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/controller.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/controller-behavior.vhdl"
|
||||
@@ -0,0 +1,4 @@
|
||||
set -tmpdir ./xst/projnav.tmp
|
||||
elaborate
|
||||
-ifn controller.prj
|
||||
-ifmt mixed
|
||||
@@ -0,0 +1,5 @@
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\dlx_types.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\dlx_instr.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\alu_types.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\controller.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\controller-behavior.vhdl"
|
||||
@@ -0,0 +1,14 @@
|
||||
## NOTE: Do not edit this file.
|
||||
## Autogenerated by ProjNav (creatfdo.tcl) on Sat Jul 08 02:17:03 Westeuropäische Sommerzeit 2006
|
||||
##
|
||||
vlib work
|
||||
vcom -explicit -93 "E:/work/lib/HDL/Cores/CPUs/DLX/dlx_types.vhdl"
|
||||
vcom -explicit -93 "E:/work/lib/HDL/Cores/CPUs/DLX/dlx_instr.vhdl"
|
||||
vcom -explicit -93 "E:/work/lib/HDL/Cores/CPUs/DLX/dlx-behavior.vhdl"
|
||||
vsim -t 1ps -lib work dlx
|
||||
do {dlx.udo}
|
||||
view wave
|
||||
add wave *
|
||||
view structure
|
||||
view signals
|
||||
run 1000ns
|
||||
@@ -0,0 +1 @@
|
||||
work
|
||||
@@ -0,0 +1,3 @@
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/dlx_types.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/dlx_instr.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/dlx-behavior.vhdl"
|
||||
@@ -0,0 +1,4 @@
|
||||
-- ProjNav VHDL simulation template: dlx.udo
|
||||
-- You may edit this file after the line that starts with
|
||||
-- '-- START' to customize your simulation
|
||||
-- START user-defined simulation commands
|
||||
@@ -0,0 +1,55 @@
|
||||
set -tmpdir ./xst/projnav.tmp
|
||||
set -xsthdpdir ./xst
|
||||
run
|
||||
-ifn dlx.prj
|
||||
-ifmt mixed
|
||||
-ofn dlx
|
||||
-ofmt NGC
|
||||
-p xc4vsx35-10-ff668
|
||||
-top dlx
|
||||
-opt_mode Speed
|
||||
-opt_level 1
|
||||
-iuc NO
|
||||
-lso dlx.lso
|
||||
-keep_hierarchy NO
|
||||
-rtlview Yes
|
||||
-glob_opt AllClockNets
|
||||
-read_cores YES
|
||||
-write_timing_constraints NO
|
||||
-cross_clock_analysis NO
|
||||
-hierarchy_separator /
|
||||
-bus_delimiter <>
|
||||
-case maintain
|
||||
-slice_utilization_ratio 100
|
||||
-dsp_utilization_ratio 100
|
||||
-verilog2001 YES
|
||||
-fsm_extract YES -fsm_encoding Auto
|
||||
-safe_implementation No
|
||||
-fsm_style lut
|
||||
-ram_extract Yes
|
||||
-ram_style Auto
|
||||
-rom_extract Yes
|
||||
-mux_style Auto
|
||||
-decoder_extract YES
|
||||
-priority_extract YES
|
||||
-shreg_extract YES
|
||||
-shift_extract YES
|
||||
-xor_collapse YES
|
||||
-rom_style Auto
|
||||
-mux_extract YES
|
||||
-resource_sharing YES
|
||||
-use_dsp48 auto
|
||||
-iobuf YES
|
||||
-max_fanout 500
|
||||
-bufg 32
|
||||
-bufr 24
|
||||
-register_duplication YES
|
||||
-register_balancing No
|
||||
-slice_packing YES
|
||||
-optimize_primitives NO
|
||||
-use_clock_enable Auto
|
||||
-use_sync_set Auto
|
||||
-use_sync_reset Auto
|
||||
-iob auto
|
||||
-equivalent_register_removal YES
|
||||
-slice_utilization_ratio_maxmargin 5
|
||||
@@ -0,0 +1,19 @@
|
||||
## NOTE: Do not edit this file.
|
||||
## Autogenerated by ProjNav (creatfdo.tcl) on Sat Jul 08 02:23:56 Westeuropäische Sommerzeit 2006
|
||||
##
|
||||
vlib work
|
||||
vcom -explicit -93 "E:/work/lib/HDL/Cores/CPUs/DLX/dlx_types.vhdl"
|
||||
vcom -explicit -93 "E:/work/lib/HDL/Cores/CPUs/DLX/dlx_instr.vhdl"
|
||||
vcom -explicit -93 "E:/work/lib/HDL/Cores/CPUs/DLX/memory.vhdl"
|
||||
vcom -explicit -93 "E:/work/lib/HDL/Cores/CPUs/DLX/dlx-behavior.vhdl"
|
||||
vcom -explicit -93 "E:/work/lib/HDL/Cores/CPUs/DLX/clock_gen.vhdl"
|
||||
vcom -explicit -93 "E:/work/lib/HDL/Cores/CPUs/DLX/memory-preloaded.vhdl"
|
||||
vcom -explicit -93 "E:/work/lib/HDL/Cores/CPUs/DLX/clock_gen-behavior.vhdl"
|
||||
vcom -explicit -93 "E:/work/lib/HDL/Cores/CPUs/DLX/dlx_test-verifier.vhdl"
|
||||
vsim -t 1ps -lib work dlx_test
|
||||
do {dlx_test.udo}
|
||||
view wave
|
||||
add wave *
|
||||
view structure
|
||||
view signals
|
||||
run 1000ns
|
||||
@@ -0,0 +1 @@
|
||||
work
|
||||
@@ -0,0 +1,28 @@
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/dlx_types.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/dlx_instr.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/alu_types.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/reg_multiple_plus_one_out_reset.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/reg_multiple_plus_one_out.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/reg_multiple_out.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/reg_file.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/reg.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/mux2.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/ir_extender.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/controller.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/alu.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/reg_multiple_plus_one_out_reset-behavior.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/reg_multiple_plus_one_out-behavior.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/reg_multiple_out-behavior.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/reg_file-behavior.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/reg-behavior.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/mux2-behavior.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/ir_extender-behavior.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/controller-behavior.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/alu-behavior.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/memory.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/dlx.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/clock_gen.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/memory-file_loaded.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/dlx-rtl.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/clock_gen-behavior.vhdl"
|
||||
vhdl work "E:/work/lib/HDL/Cores/CPUs/DLX/dlx_test-verifier.vhdl"
|
||||
@@ -0,0 +1,4 @@
|
||||
set -tmpdir ./xst/projnav.tmp
|
||||
elaborate
|
||||
-ifn dlx_test.prj
|
||||
-ifmt mixed
|
||||
@@ -0,0 +1,28 @@
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\dlx_types.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\dlx_instr.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\alu_types.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\reg_multiple_plus_one_out_reset.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\reg_multiple_plus_one_out.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\reg_multiple_out.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\reg_file.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\reg.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\mux2.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\ir_extender.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\controller.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\alu.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\reg_multiple_plus_one_out_reset-behavior.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\reg_multiple_plus_one_out-behavior.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\reg_multiple_out-behavior.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\reg_file-behavior.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\reg-behavior.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\mux2-behavior.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\ir_extender-behavior.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\controller-behavior.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\alu-behavior.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\memory.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\dlx.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\clock_gen.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\memory-file_loaded.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\dlx-rtl.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\clock_gen-behavior.vhdl"
|
||||
work "E:\work\lib\HDL\Cores\CPUs\DLX\dlx_test-verifier.vhdl"
|
||||
@@ -0,0 +1 @@
|
||||
work
|
||||
Reference in New Issue
Block a user