diff --git a/projects/dlx/dlx.tar.gz b/projects/dlx/dlx.tar.gz new file mode 100644 index 0000000..6444e44 Binary files /dev/null and b/projects/dlx/dlx.tar.gz differ diff --git a/projects/dlx/make.sh b/projects/dlx/make.sh new file mode 100644 index 0000000..193f407 --- /dev/null +++ b/projects/dlx/make.sh @@ -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 diff --git a/projects/dlx/src/README b/projects/dlx/src/README new file mode 100644 index 0000000..40ab46f --- /dev/null +++ b/projects/dlx/src/README @@ -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. diff --git a/projects/dlx/src/__DISCLAIMER.TXT b/projects/dlx/src/__DISCLAIMER.TXT new file mode 100644 index 0000000..c42b9d2 --- /dev/null +++ b/projects/dlx/src/__DISCLAIMER.TXT @@ -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. +--------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/projects/dlx/src/__README.TXT b/projects/dlx/src/__README.TXT new file mode 100644 index 0000000..c42b9d2 --- /dev/null +++ b/projects/dlx/src/__README.TXT @@ -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. +--------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/projects/dlx/src/alu-behaviour.vhdl b/projects/dlx/src/alu-behaviour.vhdl new file mode 100644 index 0000000..07bd34c --- /dev/null +++ b/projects/dlx/src/alu-behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/alu.vhdl b/projects/dlx/src/alu.vhdl new file mode 100644 index 0000000..24bc4f1 --- /dev/null +++ b/projects/dlx/src/alu.vhdl @@ -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; diff --git a/projects/dlx/src/alu_types.vhdl b/projects/dlx/src/alu_types.vhdl new file mode 100644 index 0000000..b31ff2d --- /dev/null +++ b/projects/dlx/src/alu_types.vhdl @@ -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; diff --git a/projects/dlx/src/bv_arithmetic-body.vhdl b/projects/dlx/src/bv_arithmetic-body.vhdl new file mode 100644 index 0000000..81524da --- /dev/null +++ b/projects/dlx/src/bv_arithmetic-body.vhdl @@ -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; diff --git a/projects/dlx/src/bv_arithmetic.vhdl b/projects/dlx/src/bv_arithmetic.vhdl new file mode 100644 index 0000000..e304e73 --- /dev/null +++ b/projects/dlx/src/bv_arithmetic.vhdl @@ -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; diff --git a/projects/dlx/src/bv_test-bench.vhdl b/projects/dlx/src/bv_test-bench.vhdl new file mode 100644 index 0000000..2b29d33 --- /dev/null +++ b/projects/dlx/src/bv_test-bench.vhdl @@ -0,0 +1,1121 @@ +-------------------------------------------------------------------------- +-- +-- 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-bench.vhdl,v $ $Revision: 2.1 $ $Date: 1993/10/31 20:13:16 $ +-- +-------------------------------------------------------------------------- +-- +-- Architecture for test bench for bit vector arithmetic package. +-- + + +use std.textio.all, work.bv_arithmetic.all; + +architecture bench of bv_test is + +begin + + process + + variable L : line; + variable byte : bit_vector(0 to 7); + variable word : bit_vector(1 to 32); + variable half_byte : bit_vector(1 to 4); + variable overflow, div_by_zero, result : boolean; + + begin + WAIT for 1 ns; + + ---------------------------------------------------------------- + ---------------------------------------------------------------- + -- test bit_vector to numeric conversions + ---------------------------------------------------------------- + ---------------------------------------------------------------- + + write(L, string'("Testing bv_to_natural:")); + writeline(output, L); + + write(L, string'(" bv_to_natural(X""02"") = ")); + write(L, bv_to_natural(X"02")); + writeline(output, L); + assert bv_to_natural(X"02") = 2; + + write(L, string'(" bv_to_natural(X""FE"") = ")); + write(L, bv_to_natural(X"FE")); + writeline(output, L); + assert bv_to_natural(X"FE") = 254; + + ---------------------------------------------------------------- + + write(L, string'("Testing natural_to_bv:")); + writeline(output, L); + + write(L, string'(" natural_to_bv(2) = ")); + write(L, natural_to_bv(2, 8)); + writeline(output, L); + assert natural_to_bv(2, 8) = X"02"; + + write(L, string'(" natural_to_bv(254) = ")); + write(L, natural_to_bv(254, 8)); + writeline(output, L); + assert natural_to_bv(254, 8) = X"FE"; + + ---------------------------------------------------------------- + + write(L, string'("Testing bv_to_integer:")); + writeline(output, L); + + write(L, string'(" bv_to_integer(X""02"") = ")); + write(L, bv_to_integer(X"02")); + writeline(output, L); + assert bv_to_integer(X"02") = 2; + + write(L, string'(" bv_to_integer(X""FE"") = ")); + write(L, bv_to_integer(X"FE")); + writeline(output, L); + assert bv_to_integer(X"FE") = -2; + + ---------------------------------------------------------------- + + write(L, string'("Testing integer_to_bv:")); + writeline(output, L); + + write(L, string'(" integer_to_bv(2) = ")); + write(L, integer_to_bv(2, 8)); + writeline(output, L); + assert integer_to_bv(2, 8) = X"02"; + + write(L, string'(" integer_to_bv(-2) = ")); + write(L, integer_to_bv(-2, 8)); + writeline(output, L); + assert integer_to_bv(-2, 8) = X"FE"; + + + ---------------------------------------------------------------- + ---------------------------------------------------------------- + -- Arithmetic operations + ---------------------------------------------------------------- + ---------------------------------------------------------------- + + ---------------------------------------------------------------- + -- bv_add: Signed addition with overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_add with overflow:")); + writeline(output, L); + + write(L, string'(" 2+2 = ")); + bv_add(X"02", X"02", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"04" and not overflow; + + write(L, string'(" 2+(-3) = ")); + bv_add(X"02", X"FD", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"FF" and not overflow; + + write(L, string'(" 64+64 = ")); + bv_add(X"40", X"40", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"80" and overflow; + + write(L, string'(" -64+(-64) = ")); + bv_add(X"C0", X"C0", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"80" and not overflow; + + ---------------------------------------------------------------- + -- "+": Signed addition without overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing ""+"" without overflow:")); + writeline(output, L); + + write(L, string'(" 2+2 = ")); + byte := X"02" + X"02"; + write(L, byte); + writeline(output, L); + assert byte = X"04"; + + write(L, string'(" 2+(-3) = ")); + byte := X"02" + X"FD"; + write(L, byte); + writeline(output, L); + assert byte = X"FF"; + + write(L, string'(" 64+64 = ")); + byte := X"40" + X"40"; + write(L, byte); + writeline(output, L); + assert byte = X"80"; + + write(L, string'(" -64+(-64) = ")); + byte := X"C0" + X"C0"; + write(L, byte); + writeline(output, L); + assert byte = X"80"; + + ---------------------------------------------------------------- + -- bv_sub: Signed subtraction with overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_sub with overflow:")); + writeline(output, L); + + write(L, string'(" 2-2 = ")); + bv_sub(X"02", X"02", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"00" and not overflow; + + write(L, string'(" 2-(-3) = ")); + bv_sub(X"02", X"FD", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"05" and not overflow; + + write(L, string'(" 64-(-64) = ")); + bv_sub(X"40", X"C0", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"80" and overflow; + + write(L, string'(" -64-64 = ")); + bv_sub(X"C0", X"40", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"80" and not overflow; + + ---------------------------------------------------------------- + -- "-": Signed subtraction without overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing ""-"" without overflow:")); + writeline(output, L); + + write(L, string'(" 2-2 = ")); + byte := X"02" - X"02"; + write(L, byte); + writeline(output, L); + assert byte = X"00"; + + write(L, string'(" 2-(-3) = ")); + byte := X"02" - X"FD"; + write(L, byte); + writeline(output, L); + assert byte = X"05"; + + write(L, string'(" 64-(-64) = ")); + byte := X"40" - X"C0"; + write(L, byte); + writeline(output, L); + assert byte = X"80"; + + write(L, string'(" -64-64 = ")); + byte := X"C0" - X"40"; + write(L, byte); + writeline(output, L); + assert byte = X"80"; + + ---------------------------------------------------------------- + -- bv_addu: Unsigned addition with overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_addu with overflow:")); + writeline(output, L); + + write(L, string'(" 2+2 = ")); + bv_addu(X"02", X"02", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"04" and not overflow; + + write(L, string'(" 64+64 = ")); + bv_addu(X"40", X"40", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"80" and not overflow; + + write(L, string'(" 128+128 = ")); + bv_addu(X"80", X"80", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"00" and overflow; + + ---------------------------------------------------------------- + -- bv_addu: Unsigned addition without overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_addu without overflow:")); + writeline(output, L); + + write(L, string'(" 2+2 = ")); + bv_addu(X"02", X"02", byte); + write(L, byte); + writeline(output, L); + assert byte = X"04"; + + write(L, string'(" 64+64 = ")); + bv_addu(X"40", X"40", byte); + write(L, byte); + writeline(output, L); + assert byte = X"80"; + + write(L, string'(" 128+128 = ")); + bv_addu(X"80", X"80", byte); + write(L, byte); + writeline(output, L); + assert byte = X"00"; + + ---------------------------------------------------------------- + -- bv_subu: Unsigned subtraction with overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_subu with overflow:")); + writeline(output, L); + + write(L, string'(" 3-2 = ")); + bv_subu(X"03", X"02", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"01" and not overflow; + + write(L, string'(" 64-64 = ")); + bv_subu(X"40", X"40", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"00" and not overflow; + + write(L, string'(" 64-128 = ")); + bv_subu(X"40", X"80", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"C0" and overflow; + + ---------------------------------------------------------------- + -- bv_subu: Unsigned subtraction without overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_subu without overflow:")); + writeline(output, L); + + write(L, string'(" 3-2 = ")); + bv_subu(X"03", X"02", byte); + write(L, byte); + writeline(output, L); + assert byte = X"01"; + + write(L, string'(" 64-64 = ")); + bv_subu(X"40", X"40", byte); + write(L, byte); + writeline(output, L); + assert byte = X"00"; + + write(L, string'(" 64-128 = ")); + bv_subu(X"40", X"80", byte); + write(L, byte); + writeline(output, L); + assert byte = X"C0"; + + ---------------------------------------------------------------- + -- bv_neg: Signed negation with overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_neg with overflow:")); + writeline(output, L); + + write(L, string'(" -(3) = ")); + bv_neg(X"03", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"FD" and not overflow; + + write(L, string'(" -(-3) = ")); + bv_neg(X"FD", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"03" and not overflow; + + write(L, string'(" -(127) = ")); + bv_neg(X"7F", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"81" and not overflow; + + write(L, string'(" -(-128) = ")); + bv_neg(X"80", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"80" and overflow; + + ---------------------------------------------------------------- + -- "-": Signed negation without overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing ""-"" without overflow:")); + writeline(output, L); + + write(L, string'(" -(3) = ")); + byte := - X"03"; + write(L, byte); + writeline(output, L); + assert byte = X"FD"; + + write(L, string'(" -(-3) = ")); + byte := - X"FD"; + write(L, byte); + writeline(output, L); + assert byte = X"03"; + + write(L, string'(" -(127) = ")); + byte := - X"7F"; + write(L, byte); + writeline(output, L); + assert byte = X"81"; + + write(L, string'(" -(-128) = ")); + byte := - X"80"; + write(L, byte); + writeline(output, L); + assert byte = X"80"; + + ---------------------------------------------------------------- + -- bv_mult: Signed multiplication with overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_mult with overflow:")); + writeline(output, L); + + write(L, string'(" 5*(-3) = ")); + bv_mult(X"05", X"FD", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"F1" and not overflow; + + write(L, string'(" (-5)*(-3) = ")); + bv_mult(X"FB", X"FD", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"0F" and not overflow; + + write(L, string'(" 16*8 = ")); + bv_mult(X"10", X"08", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"80" and overflow; + + write(L, string'(" 16*16 = ")); + bv_mult(X"10", X"10", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"00" and overflow; + + write(L, string'(" 16*(-8) = ")); + bv_mult(X"10", X"F8", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"80" and not overflow; + + write(L, string'(" 16*(-16) = ")); + bv_mult(X"10", X"F0", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"00" and overflow; + + ---------------------------------------------------------------- + -- "*": Signed multiplication without overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing ""*"" without overflow:")); + writeline(output, L); + + write(L, string'(" 5*(-3) = ")); + byte := X"05" * X"FD"; + write(L, byte); + writeline(output, L); + assert byte = X"F1"; + + write(L, string'(" (-5)*(-3) = ")); + byte := X"FB" * X"FD"; + write(L, byte); + writeline(output, L); + assert byte = X"0F"; + + write(L, string'(" 16*8 = ")); + byte := X"10" * X"08"; + write(L, byte); + writeline(output, L); + assert byte = X"80"; + + write(L, string'(" 16*16 = ")); + byte := X"10" * X"10"; + write(L, byte); + writeline(output, L); + assert byte = X"00"; + + write(L, string'(" 16*(-8) = ")); + byte := X"10" * X"F8"; + write(L, byte); + writeline(output, L); + assert byte = X"80"; + + write(L, string'(" 16*(-16) = ")); + byte := X"10" * X"F0"; + write(L, byte); + writeline(output, L); + assert byte = X"00"; + + ---------------------------------------------------------------- + -- bv_multu: Unsigned multiplication with overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_multu with overflow:")); + writeline(output, L); + + write(L, string'(" 5*7 = ")); + bv_multu(X"05", X"07", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"23" and not overflow; + + write(L, string'(" 16*8 = ")); + bv_multu(X"10", X"08", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"80" and not overflow; + + write(L, string'(" 16*16 = ")); + bv_multu(X"10", X"10", byte, overflow); + write(L, byte); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"00" and overflow; + + ---------------------------------------------------------------- + -- bv_multu: Unsigned multiplication without overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_multu without overflow:")); + writeline(output, L); + + write(L, string'(" 5*7 = ")); + bv_multu(X"05", X"07", byte); + write(L, byte); + writeline(output, L); + assert byte = X"23"; + + write(L, string'(" 16*8 = ")); + bv_multu(X"10", X"08", byte); + write(L, byte); + writeline(output, L); + assert byte = X"80"; + + write(L, string'(" 16*16 = ")); + bv_multu(X"10", X"10", byte); + write(L, byte); + writeline(output, L); + assert byte = X"00"; + + ---------------------------------------------------------------- + -- bv_div: Signed division with divide by zero and overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_div with flags:")); + writeline(output, L); + + write(L, string'(" 7/2 = ")); + bv_div(X"07", X"02", byte, div_by_zero, overflow); + write(L, byte); + write(L, string'(", div_by_zero = ")); write(L, div_by_zero); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"03" and not div_by_zero and not overflow; + + write(L, string'(" -7/2 = ")); + bv_div(X"F9", X"02", byte, div_by_zero, overflow); + write(L, byte); + write(L, string'(", div_by_zero = ")); write(L, div_by_zero); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"FD" and not div_by_zero and not overflow; + + write(L, string'(" 7/-2 = ")); + bv_div(X"07", X"FE", byte, div_by_zero, overflow); + write(L, byte); + write(L, string'(", div_by_zero = ")); write(L, div_by_zero); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"FD" and not div_by_zero and not overflow; + + write(L, string'(" -7/-2 = ")); + bv_div(X"F9", X"FE", byte, div_by_zero, overflow); + write(L, byte); + write(L, string'(", div_by_zero = ")); write(L, div_by_zero); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"03" and not div_by_zero and not overflow; + + write(L, string'(" -128/1 = ")); + bv_div(X"80", X"01", byte, div_by_zero, overflow); + write(L, byte); + write(L, string'(", div_by_zero = ")); write(L, div_by_zero); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"80" and not div_by_zero and not overflow; + + write(L, string'(" -128/-1 = ")); + bv_div(X"80", X"FF", byte, div_by_zero, overflow); + write(L, byte); + write(L, string'(", div_by_zero = ")); write(L, div_by_zero); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"80" and not div_by_zero and overflow; + + write(L, string'(" -16/0 = ")); + bv_div(X"F0", X"00", byte, div_by_zero, overflow); + write(L, byte); + write(L, string'(", div_by_zero = ")); write(L, div_by_zero); + write(L, string'(", overflow = ")); write(L, overflow); + writeline(output, L); + assert byte = X"00" and div_by_zero and not overflow; + + ---------------------------------------------------------------- + -- "/": Signed division without divide by zero and overflow detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing ""/"" without flags:")); + writeline(output, L); + + write(L, string'(" 7/2 = ")); + byte := X"07" / X"02"; + write(L, byte); + writeline(output, L); + assert byte = X"03"; + + write(L, string'(" -7/2 = ")); + byte := X"F9" / X"02"; + write(L, byte); + writeline(output, L); + assert byte = X"FD"; + + write(L, string'(" 7/-2 = ")); + byte := X"07" / X"FE"; + write(L, byte); + writeline(output, L); + assert byte = X"FD"; + + write(L, string'(" -7/-2 = ")); + byte := X"F9" / X"FE"; + write(L, byte); + writeline(output, L); + assert byte = X"03"; + + write(L, string'(" -128/1 = ")); + byte := X"80" / X"01"; + write(L, byte); + writeline(output, L); + assert byte = X"80"; + + write(L, string'(" -128/-1 = ")); + byte := X"80" / X"FF"; + write(L, byte); + writeline(output, L); + assert byte = X"80"; + + write(L, string'(" -16/0 = ")); + byte := X"F0" / X"00"; + write(L, byte); + writeline(output, L); + assert byte = X"00"; + + ---------------------------------------------------------------- + -- bv_divu: Unsigned division with divide by zero detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_divu with flag:")); + writeline(output, L); + + write(L, string'(" 7/2 = ")); + bv_divu(X"07", X"02", byte, div_by_zero); + write(L, byte); + write(L, string'(", div_by_zero = ")); write(L, div_by_zero); + writeline(output, L); + assert byte = X"03" and not div_by_zero; + + write(L, string'(" 14/7 = ")); + bv_divu(X"0E", X"07", byte, div_by_zero); + write(L, byte); + write(L, string'(", div_by_zero = ")); write(L, div_by_zero); + writeline(output, L); + assert byte = X"02" and not div_by_zero; + + write(L, string'(" 16/1 = ")); + bv_divu(X"10", X"01", byte, div_by_zero); + write(L, byte); + write(L, string'(", div_by_zero = ")); write(L, div_by_zero); + writeline(output, L); + assert byte = X"10" and not div_by_zero; + + write(L, string'(" 16/0 = ")); + bv_divu(X"10", X"00", byte, div_by_zero); + write(L, byte); + write(L, string'(", div_by_zero = ")); write(L, div_by_zero); + writeline(output, L); + assert byte = X"10" and div_by_zero; + + write(L, string'(" 16/16 = ")); + bv_divu(X"10", X"10", byte, div_by_zero); + write(L, byte); + write(L, string'(", div_by_zero = ")); write(L, div_by_zero); + writeline(output, L); + assert byte = X"01" and not div_by_zero; + + write(L, string'(" 1/16 = ")); + bv_divu(X"01", X"10", byte, div_by_zero); + write(L, byte); + write(L, string'(", div_by_zero = ")); write(L, div_by_zero); + writeline(output, L); + assert byte = X"00" and not div_by_zero; + + write(L, string'(" 255/1 = ")); + bv_divu(X"FF", X"01", byte, div_by_zero); + write(L, byte); + write(L, string'(", div_by_zero = ")); write(L, div_by_zero); + writeline(output, L); + assert byte = X"FF" and not div_by_zero; + + ---------------------------------------------------------------- + -- bv_divu: Unsigned division without divide by zero detection + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_divu without flag:")); + writeline(output, L); + + write(L, string'(" 7/2 = ")); + bv_divu(X"07", X"02", byte); + write(L, byte); + writeline(output, L); + assert byte = X"03"; + + write(L, string'(" 14/7 = ")); + bv_divu(X"0E", X"07", byte); + write(L, byte); + writeline(output, L); + assert byte = X"02"; + + write(L, string'(" 16/1 = ")); + bv_divu(X"10", X"01", byte); + write(L, byte); + writeline(output, L); + assert byte = X"10"; + + write(L, string'(" 16/0 = ")); + bv_divu(X"10", X"00", byte); + write(L, byte); + writeline(output, L); + assert byte = X"10"; + + write(L, string'(" 16/16 = ")); + bv_divu(X"10", X"10", byte); + write(L, byte); + writeline(output, L); + assert byte = X"01"; + + write(L, string'(" 1/16 = ")); + bv_divu(X"01", X"10", byte); + write(L, byte); + writeline(output, L); + assert byte = X"00"; + + write(L, string'(" 255/1 = ")); + bv_divu(X"FF", X"01", byte); + write(L, byte); + writeline(output, L); + assert byte = X"FF"; + + + ---------------------------------------------------------------- + ---------------------------------------------------------------- + -- Logical operators + -- (Provided for VHDL-87, built in for VHDL-93) + ---------------------------------------------------------------- + ---------------------------------------------------------------- + + ---------------------------------------------------------------- + -- bv_sll: Shift left logical (fill with '0' bits) + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_sll:")); + writeline(output, L); + + write(L, string'(" 10100101 sll 4 = ")); + byte := bv_sll(B"10100101", 4); + write(L, byte); + writeline(output, L); + assert byte = B"01010000"; + + ---------------------------------------------------------------- + -- bv_srl: Shift right logical (fill with '0' bits) + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_srl:")); + writeline(output, L); + + write(L, string'(" 10100101 srl 4 = ")); + byte := bv_srl(B"10100101", 4); + write(L, byte); + writeline(output, L); + assert byte = B"00001010"; + + ---------------------------------------------------------------- + -- bv_sra: Shift right arithmetic (fill with copy of sign bit) + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_sra:")); + writeline(output, L); + + write(L, string'(" 01011010 sra 4 = ")); + byte := bv_sra(B"01011010", 4); + write(L, byte); + writeline(output, L); + assert byte = B"00000101"; + + write(L, string'(" 10100101 sra 4 = ")); + byte := bv_sra(B"10100101", 4); + write(L, byte); + writeline(output, L); + assert byte = B"11111010"; + + ---------------------------------------------------------------- + -- bv_rol: Rotate left + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_rol:")); + writeline(output, L); + + write(L, string'(" 10100101 rol 3 = ")); + byte := bv_rol(B"10100101", 3); + write(L, byte); + writeline(output, L); + assert byte = B"00101101"; + + ---------------------------------------------------------------- + -- bv_rol: Rotate right + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_ror:")); + writeline(output, L); + + write(L, string'(" 10100101 ror 3 = ")); + byte := bv_ror(B"10100101", 3); + write(L, byte); + writeline(output, L); + assert byte = B"10110100"; + + + ---------------------------------------------------------------- + ---------------------------------------------------------------- + -- Arithmetic comparison operators. + ---------------------------------------------------------------- + ---------------------------------------------------------------- + + ---------------------------------------------------------------- + -- bv_lt: Signed less than comparison + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_lt:")); + writeline(output, L); + + write(L, string'(" 2 < 2 = ")); + result := bv_lt(X"02", X"02"); + write(L, result); + writeline(output, L); + assert NOT result; + + write(L, string'(" 2 < 3 = ")); + result := bv_lt(X"02", X"03"); + write(L, result); + writeline(output, L); + assert result; + + write(L, string'(" -2 < 2 = ")); + result := bv_lt(X"FE", X"02"); + write(L, result); + writeline(output, L); + assert result; + + write(L, string'(" 2 < -3 = ")); + result := bv_lt(X"02", X"FD"); + write(L, result); + writeline(output, L); + assert NOT result; + + ---------------------------------------------------------------- + -- bv_le: Signed less than or equal comparison + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_le:")); + writeline(output, L); + + write(L, string'(" 2 <= 2 = ")); + result := bv_le(X"02", X"02"); + write(L, result); + writeline(output, L); + assert result; + + write(L, string'(" 2 <= 3 = ")); + result := bv_le(X"02", X"03"); + write(L, result); + writeline(output, L); + assert result; + + write(L, string'(" -2 <= 2 = ")); + result := bv_le(X"FE", X"02"); + write(L, result); + writeline(output, L); + assert result; + + write(L, string'(" 2 <= -3 = ")); + result := bv_le(X"02", X"FD"); + write(L, result); + writeline(output, L); + assert NOT result; + + ---------------------------------------------------------------- + -- bv_gt: Signed greater than comparison + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_gt:")); + writeline(output, L); + + write(L, string'(" 2 > 2 = ")); + result := bv_gt(X"02", X"02"); + write(L, result); + writeline(output, L); + assert NOT result; + + write(L, string'(" 3 > 2 = ")); + result := bv_gt(X"03", X"02"); + write(L, result); + writeline(output, L); + assert result; + + write(L, string'(" 2 > -2 = ")); + result := bv_gt(X"02", X"FE"); + write(L, result); + writeline(output, L); + assert result; + + write(L, string'(" -3 > 2 = ")); + result := bv_gt(X"FD", X"02"); + write(L, result); + writeline(output, L); + assert NOT result; + + ---------------------------------------------------------------- + -- bv_ge: Signed greater than or equal comparison + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_ge:")); + writeline(output, L); + + write(L, string'(" 2 >= 2 = ")); + result := bv_ge(X"02", X"02"); + write(L, result); + writeline(output, L); + assert result; + + write(L, string'(" 3 >= 2 = ")); + result := bv_ge(X"03", X"02"); + write(L, result); + writeline(output, L); + assert result; + + write(L, string'(" 2 >= -2 = ")); + result := bv_ge(X"02", X"FE"); + write(L, result); + writeline(output, L); + assert result; + + write(L, string'(" -3 >= 2 = ")); + result := bv_ge(X"FD", X"02"); + write(L, result); + writeline(output, L); + assert NOT result; + + ---------------------------------------------------------------- + ---------------------------------------------------------------- + -- Extension operators - convert a bit vector to a longer one + ---------------------------------------------------------------- + ---------------------------------------------------------------- + + ---------------------------------------------------------------- + -- bv_sext: Sign extension + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_sext:")); + writeline(output, L); + + write(L, string'(" sext(X""02"", 32) = ")); + word := bv_sext(X"02", 32); + write(L, word); + writeline(output, L); + assert word = X"00000002"; + + write(L, string'(" sext(X""FE"", 32) = ")); + word := bv_sext(X"FE", 32); + write(L, word); + writeline(output, L); + assert word = X"FFFFFFFE"; + + write(L, string'(" sext(X""02"", 8) = ")); + byte := bv_sext(X"02", 8); + write(L, byte); + writeline(output, L); + assert byte = X"02"; + + write(L, string'(" sext(X""FE"", 8) = ")); + byte := bv_sext(X"FE", 8); + write(L, byte); + writeline(output, L); + assert byte = X"FE"; + + write(L, string'(" sext(X""02"", 4) = ")); + half_byte := bv_sext(X"02", 4); + write(L, half_byte); + writeline(output, L); + assert half_byte = X"2"; + + write(L, string'(" sext(X""FE"", 4) = ")); + half_byte := bv_sext(X"FE", 4); + write(L, half_byte); + writeline(output, L); + assert half_byte = X"E"; + + ---------------------------------------------------------------- + -- bv_zext" Zero extension + ---------------------------------------------------------------- + + writeline(output, L); + write(L, string'("Testing bv_zext:")); + writeline(output, L); + + write(L, string'(" zext(X""02"", 32) = ")); + word := bv_zext(X"02", 32); + write(L, word); + writeline(output, L); + assert word = X"00000002"; + + write(L, string'(" zext(X""FE"", 32) = ")); + word := bv_zext(X"FE", 32); + write(L, word); + writeline(output, L); + assert word = X"000000FE"; + + write(L, string'(" zext(X""02"", 8) = ")); + byte := bv_zext(X"02", 8); + write(L, byte); + writeline(output, L); + assert byte = X"02"; + + write(L, string'(" zext(X""FE"", 8) = ")); + byte := bv_zext(X"FE", 8); + write(L, byte); + writeline(output, L); + assert byte = X"FE"; + + write(L, string'(" zext(X""02"", 4) = ")); + half_byte := bv_zext(X"02", 4); + write(L, half_byte); + writeline(output, L); + assert half_byte = X"2"; + + write(L, string'(" zext(X""FE"", 4) = ")); + half_byte := bv_zext(X"FE", 4); + write(L, half_byte); + writeline(output, L); + assert half_byte = X"E"; + + + wait; + end process; + +end bench; diff --git a/projects/dlx/src/bv_test.vhdl b/projects/dlx/src/bv_test.vhdl new file mode 100644 index 0000000..f7d231c --- /dev/null +++ b/projects/dlx/src/bv_test.vhdl @@ -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; diff --git a/projects/dlx/src/cache-behaviour.vhdl b/projects/dlx/src/cache-behaviour.vhdl new file mode 100644 index 0000000..4f9dfb7 --- /dev/null +++ b/projects/dlx/src/cache-behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/cache.vhdl b/projects/dlx/src/cache.vhdl new file mode 100644 index 0000000..9b9d862 --- /dev/null +++ b/projects/dlx/src/cache.vhdl @@ -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; diff --git a/projects/dlx/src/cache_types.vhdl b/projects/dlx/src/cache_types.vhdl new file mode 100644 index 0000000..aff9a27 --- /dev/null +++ b/projects/dlx/src/cache_types.vhdl @@ -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; diff --git a/projects/dlx/src/clock_gen-behaviour.vhdl b/projects/dlx/src/clock_gen-behaviour.vhdl new file mode 100644 index 0000000..4ac8042 --- /dev/null +++ b/projects/dlx/src/clock_gen-behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/clock_gen.vhdl b/projects/dlx/src/clock_gen.vhdl new file mode 100644 index 0000000..3c5a48e --- /dev/null +++ b/projects/dlx/src/clock_gen.vhdl @@ -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; diff --git a/projects/dlx/src/clock_gen_test-bench.vhdl b/projects/dlx/src/clock_gen_test-bench.vhdl new file mode 100644 index 0000000..a3d4395 --- /dev/null +++ b/projects/dlx/src/clock_gen_test-bench.vhdl @@ -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; diff --git a/projects/dlx/src/clock_gen_test.vhdl b/projects/dlx/src/clock_gen_test.vhdl new file mode 100644 index 0000000..d4c9422 --- /dev/null +++ b/projects/dlx/src/clock_gen_test.vhdl @@ -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; diff --git a/projects/dlx/src/controller-behaviour.vhdl b/projects/dlx/src/controller-behaviour.vhdl new file mode 100644 index 0000000..251c3be --- /dev/null +++ b/projects/dlx/src/controller-behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/controller.vhdl b/projects/dlx/src/controller.vhdl new file mode 100644 index 0000000..fac18f6 --- /dev/null +++ b/projects/dlx/src/controller.vhdl @@ -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; diff --git a/projects/dlx/src/distribution-manifest b/projects/dlx/src/distribution-manifest new file mode 100644 index 0000000..a24c9dc --- /dev/null +++ b/projects/dlx/src/distribution-manifest @@ -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 diff --git a/projects/dlx/src/dlx-behaviour.vhdl b/projects/dlx/src/dlx-behaviour.vhdl new file mode 100644 index 0000000..4e8507a --- /dev/null +++ b/projects/dlx/src/dlx-behaviour.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; diff --git a/projects/dlx/src/dlx-instrumented.vhdl b/projects/dlx/src/dlx-instrumented.vhdl new file mode 100644 index 0000000..0faacd7 --- /dev/null +++ b/projects/dlx/src/dlx-instrumented.vhdl @@ -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; diff --git a/projects/dlx/src/dlx-rtl.vhdl b/projects/dlx/src/dlx-rtl.vhdl new file mode 100644 index 0000000..21ce048 --- /dev/null +++ b/projects/dlx/src/dlx-rtl.vhdl @@ -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; diff --git a/projects/dlx/src/dlx.vhdl b/projects/dlx/src/dlx.vhdl new file mode 100644 index 0000000..b384d92 --- /dev/null +++ b/projects/dlx/src/dlx.vhdl @@ -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; diff --git a/projects/dlx/src/dlx_bus_monitor-behaviour.vhdl b/projects/dlx/src/dlx_bus_monitor-behaviour.vhdl new file mode 100644 index 0000000..1873e73 --- /dev/null +++ b/projects/dlx/src/dlx_bus_monitor-behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/dlx_bus_monitor.vhdl b/projects/dlx/src/dlx_bus_monitor.vhdl new file mode 100644 index 0000000..ccac761 --- /dev/null +++ b/projects/dlx/src/dlx_bus_monitor.vhdl @@ -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; diff --git a/projects/dlx/src/dlx_instr-body.vhdl b/projects/dlx/src/dlx_instr-body.vhdl new file mode 100644 index 0000000..69b3095 --- /dev/null +++ b/projects/dlx/src/dlx_instr-body.vhdl @@ -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; diff --git a/projects/dlx/src/dlx_instr.vhdl b/projects/dlx/src/dlx_instr.vhdl new file mode 100644 index 0000000..499f11b --- /dev/null +++ b/projects/dlx/src/dlx_instr.vhdl @@ -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; diff --git a/projects/dlx/src/dlx_test-bench.vhdl b/projects/dlx/src/dlx_test-bench.vhdl new file mode 100644 index 0000000..98fa114 --- /dev/null +++ b/projects/dlx/src/dlx_test-bench.vhdl @@ -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; diff --git a/projects/dlx/src/dlx_test-bench_cache.vhdl b/projects/dlx/src/dlx_test-bench_cache.vhdl new file mode 100644 index 0000000..f1ead7b --- /dev/null +++ b/projects/dlx/src/dlx_test-bench_cache.vhdl @@ -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; diff --git a/projects/dlx/src/dlx_test.vhdl b/projects/dlx/src/dlx_test.vhdl new file mode 100644 index 0000000..02cb3d9 --- /dev/null +++ b/projects/dlx/src/dlx_test.vhdl @@ -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; diff --git a/projects/dlx/src/dlx_test_behaviour.vhdl b/projects/dlx/src/dlx_test_behaviour.vhdl new file mode 100644 index 0000000..b8f8f83 --- /dev/null +++ b/projects/dlx/src/dlx_test_behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/dlx_test_cache.vhdl b/projects/dlx/src/dlx_test_cache.vhdl new file mode 100644 index 0000000..1568a97 --- /dev/null +++ b/projects/dlx/src/dlx_test_cache.vhdl @@ -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; diff --git a/projects/dlx/src/dlx_test_instrumented.vhdl b/projects/dlx/src/dlx_test_instrumented.vhdl new file mode 100644 index 0000000..46ff96a --- /dev/null +++ b/projects/dlx/src/dlx_test_instrumented.vhdl @@ -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; diff --git a/projects/dlx/src/dlx_test_rtl.vhdl b/projects/dlx/src/dlx_test_rtl.vhdl new file mode 100644 index 0000000..9271536 --- /dev/null +++ b/projects/dlx/src/dlx_test_rtl.vhdl @@ -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; diff --git a/projects/dlx/src/dlx_types-body.vhdl b/projects/dlx/src/dlx_types-body.vhdl new file mode 100644 index 0000000..1dc4c51 --- /dev/null +++ b/projects/dlx/src/dlx_types-body.vhdl @@ -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; diff --git a/projects/dlx/src/dlx_types.vhdl b/projects/dlx/src/dlx_types.vhdl new file mode 100644 index 0000000..feec534 --- /dev/null +++ b/projects/dlx/src/dlx_types.vhdl @@ -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; diff --git a/projects/dlx/src/images-body.vhdl b/projects/dlx/src/images-body.vhdl new file mode 100644 index 0000000..61edbce --- /dev/null +++ b/projects/dlx/src/images-body.vhdl @@ -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; diff --git a/projects/dlx/src/images.vhdl b/projects/dlx/src/images.vhdl new file mode 100644 index 0000000..72ac30a --- /dev/null +++ b/projects/dlx/src/images.vhdl @@ -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; + diff --git a/projects/dlx/src/images_test-bench.vhdl b/projects/dlx/src/images_test-bench.vhdl new file mode 100644 index 0000000..619ce70 --- /dev/null +++ b/projects/dlx/src/images_test-bench.vhdl @@ -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; + + diff --git a/projects/dlx/src/images_test.vhdl b/projects/dlx/src/images_test.vhdl new file mode 100644 index 0000000..5eb4389 --- /dev/null +++ b/projects/dlx/src/images_test.vhdl @@ -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; + + diff --git a/projects/dlx/src/ir-behaviour.vhdl b/projects/dlx/src/ir-behaviour.vhdl new file mode 100644 index 0000000..ff432f2 --- /dev/null +++ b/projects/dlx/src/ir-behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/ir.vhdl b/projects/dlx/src/ir.vhdl new file mode 100644 index 0000000..d7640b0 --- /dev/null +++ b/projects/dlx/src/ir.vhdl @@ -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; diff --git a/projects/dlx/src/latch-behaviour.vhdl b/projects/dlx/src/latch-behaviour.vhdl new file mode 100644 index 0000000..54fbb8d --- /dev/null +++ b/projects/dlx/src/latch-behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/latch.vhdl b/projects/dlx/src/latch.vhdl new file mode 100644 index 0000000..7f8653f --- /dev/null +++ b/projects/dlx/src/latch.vhdl @@ -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; diff --git a/projects/dlx/src/mem_types.vhdl b/projects/dlx/src/mem_types.vhdl new file mode 100644 index 0000000..9dc2e97 --- /dev/null +++ b/projects/dlx/src/mem_types.vhdl @@ -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; diff --git a/projects/dlx/src/memory-behaviour.vhdl b/projects/dlx/src/memory-behaviour.vhdl new file mode 100644 index 0000000..1cee156 --- /dev/null +++ b/projects/dlx/src/memory-behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/memory.vhdl b/projects/dlx/src/memory.vhdl new file mode 100644 index 0000000..7051901 --- /dev/null +++ b/projects/dlx/src/memory.vhdl @@ -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; diff --git a/projects/dlx/src/memory_test-bench.vhdl b/projects/dlx/src/memory_test-bench.vhdl new file mode 100644 index 0000000..a54e35b --- /dev/null +++ b/projects/dlx/src/memory_test-bench.vhdl @@ -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; diff --git a/projects/dlx/src/memory_test.vhdl b/projects/dlx/src/memory_test.vhdl new file mode 100644 index 0000000..976caef --- /dev/null +++ b/projects/dlx/src/memory_test.vhdl @@ -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; diff --git a/projects/dlx/src/module-directory b/projects/dlx/src/module-directory new file mode 100644 index 0000000..4d5523d --- /dev/null +++ b/projects/dlx/src/module-directory @@ -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. + diff --git a/projects/dlx/src/mux2-behaviour.vhdl b/projects/dlx/src/mux2-behaviour.vhdl new file mode 100644 index 0000000..20c73ad --- /dev/null +++ b/projects/dlx/src/mux2-behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/mux2.vhdl b/projects/dlx/src/mux2.vhdl new file mode 100644 index 0000000..69d122b --- /dev/null +++ b/projects/dlx/src/mux2.vhdl @@ -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; diff --git a/projects/dlx/src/reg_1_out-behaviour.vhdl b/projects/dlx/src/reg_1_out-behaviour.vhdl new file mode 100644 index 0000000..6a84717 --- /dev/null +++ b/projects/dlx/src/reg_1_out-behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/reg_1_out.vhdl b/projects/dlx/src/reg_1_out.vhdl new file mode 100644 index 0000000..a43d75d --- /dev/null +++ b/projects/dlx/src/reg_1_out.vhdl @@ -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; diff --git a/projects/dlx/src/reg_2_1_out-behaviour.vhdl b/projects/dlx/src/reg_2_1_out-behaviour.vhdl new file mode 100644 index 0000000..6339ce9 --- /dev/null +++ b/projects/dlx/src/reg_2_1_out-behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/reg_2_1_out.vhdl b/projects/dlx/src/reg_2_1_out.vhdl new file mode 100644 index 0000000..c0767c5 --- /dev/null +++ b/projects/dlx/src/reg_2_1_out.vhdl @@ -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; diff --git a/projects/dlx/src/reg_2_out-behaviour.vhdl b/projects/dlx/src/reg_2_out-behaviour.vhdl new file mode 100644 index 0000000..585bfe6 --- /dev/null +++ b/projects/dlx/src/reg_2_out-behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/reg_2_out.vhdl b/projects/dlx/src/reg_2_out.vhdl new file mode 100644 index 0000000..43f5cfc --- /dev/null +++ b/projects/dlx/src/reg_2_out.vhdl @@ -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; diff --git a/projects/dlx/src/reg_3_out-behaviour.vhdl b/projects/dlx/src/reg_3_out-behaviour.vhdl new file mode 100644 index 0000000..7f5208d --- /dev/null +++ b/projects/dlx/src/reg_3_out-behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/reg_3_out.vhdl b/projects/dlx/src/reg_3_out.vhdl new file mode 100644 index 0000000..84a4d5e --- /dev/null +++ b/projects/dlx/src/reg_3_out.vhdl @@ -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; diff --git a/projects/dlx/src/reg_file-behaviour.vhdl b/projects/dlx/src/reg_file-behaviour.vhdl new file mode 100644 index 0000000..ec39c67 --- /dev/null +++ b/projects/dlx/src/reg_file-behaviour.vhdl @@ -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; diff --git a/projects/dlx/src/reg_file.vhdl b/projects/dlx/src/reg_file.vhdl new file mode 100644 index 0000000..0bab518 --- /dev/null +++ b/projects/dlx/src/reg_file.vhdl @@ -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; diff --git a/projects/dlx/src/simple.out b/projects/dlx/src/simple.out new file mode 100644 index 0000000..60b5c17 --- /dev/null +++ b/projects/dlx/src/simple.out @@ -0,0 +1,2 @@ +00000000 20020000 +00000004 44000000 diff --git a/projects/dlx/src/simple.s b/projects/dlx/src/simple.s new file mode 100644 index 0000000..ff51d33 --- /dev/null +++ b/projects/dlx/src/simple.s @@ -0,0 +1,3 @@ + .text 0 + addi r2, r0, 0 ; r2 := 0 + trap 0 diff --git a/projects/dlx/src/test_loop.out b/projects/dlx/src/test_loop.out new file mode 100644 index 0000000..ed3bf6b --- /dev/null +++ b/projects/dlx/src/test_loop.out @@ -0,0 +1,6 @@ +00000000 20020000 +00000004 ac020018 +00000008 20420001 +0000000c 6441000a +00000010 1420fff0 +00000014 44000000 diff --git a/projects/dlx/src/test_loop.s b/projects/dlx/src/test_loop.s new file mode 100644 index 0000000..e3c56e7 --- /dev/null +++ b/projects/dlx/src/test_loop.s @@ -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 diff --git a/projects/dlx/syn/ise/project/controller.prj b/projects/dlx/syn/ise/project/controller.prj new file mode 100644 index 0000000..85def89 --- /dev/null +++ b/projects/dlx/syn/ise/project/controller.prj @@ -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" diff --git a/projects/dlx/syn/ise/project/controller.xst b/projects/dlx/syn/ise/project/controller.xst new file mode 100644 index 0000000..c2b33b1 --- /dev/null +++ b/projects/dlx/syn/ise/project/controller.xst @@ -0,0 +1,4 @@ +set -tmpdir ./xst/projnav.tmp +elaborate +-ifn controller.prj +-ifmt mixed diff --git a/projects/dlx/syn/ise/project/controller_vhdl.prj b/projects/dlx/syn/ise/project/controller_vhdl.prj new file mode 100644 index 0000000..22b1376 --- /dev/null +++ b/projects/dlx/syn/ise/project/controller_vhdl.prj @@ -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" diff --git a/projects/dlx/syn/ise/project/dlx.fdo b/projects/dlx/syn/ise/project/dlx.fdo new file mode 100644 index 0000000..17ee927 --- /dev/null +++ b/projects/dlx/syn/ise/project/dlx.fdo @@ -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 diff --git a/projects/dlx/syn/ise/project/dlx.lso b/projects/dlx/syn/ise/project/dlx.lso new file mode 100644 index 0000000..22de730 --- /dev/null +++ b/projects/dlx/syn/ise/project/dlx.lso @@ -0,0 +1 @@ +work diff --git a/projects/dlx/syn/ise/project/dlx.prj b/projects/dlx/syn/ise/project/dlx.prj new file mode 100644 index 0000000..28cf02e --- /dev/null +++ b/projects/dlx/syn/ise/project/dlx.prj @@ -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" diff --git a/projects/dlx/syn/ise/project/dlx.udo b/projects/dlx/syn/ise/project/dlx.udo new file mode 100644 index 0000000..2adcb27 --- /dev/null +++ b/projects/dlx/syn/ise/project/dlx.udo @@ -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 diff --git a/projects/dlx/syn/ise/project/dlx.xst b/projects/dlx/syn/ise/project/dlx.xst new file mode 100644 index 0000000..d2d0217 --- /dev/null +++ b/projects/dlx/syn/ise/project/dlx.xst @@ -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 diff --git a/projects/dlx/syn/ise/project/dlx_test.fdo b/projects/dlx/syn/ise/project/dlx_test.fdo new file mode 100644 index 0000000..a14aa1f --- /dev/null +++ b/projects/dlx/syn/ise/project/dlx_test.fdo @@ -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 diff --git a/projects/dlx/syn/ise/project/dlx_test.lso b/projects/dlx/syn/ise/project/dlx_test.lso new file mode 100644 index 0000000..22de730 --- /dev/null +++ b/projects/dlx/syn/ise/project/dlx_test.lso @@ -0,0 +1 @@ +work diff --git a/projects/dlx/syn/ise/project/dlx_test.prj b/projects/dlx/syn/ise/project/dlx_test.prj new file mode 100644 index 0000000..f56c4ac --- /dev/null +++ b/projects/dlx/syn/ise/project/dlx_test.prj @@ -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" diff --git a/projects/dlx/syn/ise/project/dlx_test.xst b/projects/dlx/syn/ise/project/dlx_test.xst new file mode 100644 index 0000000..af56ea5 --- /dev/null +++ b/projects/dlx/syn/ise/project/dlx_test.xst @@ -0,0 +1,4 @@ +set -tmpdir ./xst/projnav.tmp +elaborate +-ifn dlx_test.prj +-ifmt mixed diff --git a/projects/dlx/syn/ise/project/dlx_test_vhdl.prj b/projects/dlx/syn/ise/project/dlx_test_vhdl.prj new file mode 100644 index 0000000..4005546 --- /dev/null +++ b/projects/dlx/syn/ise/project/dlx_test_vhdl.prj @@ -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" diff --git a/projects/dlx/syn/ise/project/prjname.lso b/projects/dlx/syn/ise/project/prjname.lso new file mode 100644 index 0000000..22de730 --- /dev/null +++ b/projects/dlx/syn/ise/project/prjname.lso @@ -0,0 +1 @@ +work