|
Message
From: cvs at opencores.org<cvs@o...>
Date: Sun Dec 31 19:55:36 CET 2006
Subject: [cvs-checkins] MODIFIED: rise ...
Date: 00/06/12 31:19:55 Modified: rise/vhdl ex_stage.vhd rise_pack.vhd rlu.vhd Added: rise/vhdl tb_ex_stage_unit.vhd tb_rlu_unit.vhd Log: Implementation of execute stage and register lock unit. Some changes im RISE package. Revision Changes Path 1.2 rise/vhdl/ex_stage.vhd http://www.opencores.org/cvsweb.shtml/rise/vhdl/ex_stage.vhd.diff?r1=1.1&r2=1.2 (In the diff below, changes in quantity of whitespace are not shown.) Index: ex_stage.vhd =================================================================== RCS file: /cvsroot/jlechner/rise/vhdl/ex_stage.vhd,v retrieving revision 1.1 retrieving revision 1.2 diff -u -b -r1.1 -r1.2 --- ex_stage.vhd 6 Dec 2006 22:41:04 -0000 1.1 +++ ex_stage.vhd 31 Dec 2006 18:55:35 -0000 1.2 @@ -1,3 +1,4 @@ +------------------------------------------------------------------------------- -- File: ex_stage.vhd -- Author: Jakob Lechner, Urban Stadler, Harald Trinkl, Christian Walter -- Created: 2006-11-29 @@ -9,11 +10,11 @@ library IEEE; use IEEE.STD_LOGIC_1164.all; +use IEEE.std_logic_signed.all; use IEEE.STD_LOGIC_ARITH.all; use WORK.RISE_PACK.all; - entity ex_stage is port ( @@ -32,21 +33,250 @@ architecture ex_stage_rtl of ex_stage is +-- signal id_ex_register : ID_EX_REGISTER_T; + signal ex_mem_register_int : EX_MEM_REGISTER_T; signal ex_mem_register_next : EX_MEM_REGISTER_T; + signal isLoadOp : std_logic; + signal isJmpOp : std_logic; + + signal aluop1_int : ALUOP1_T; + signal aluop2_int : ALUOP2_T; + + signal execute : std_logic; + signal clear_out_int : std_logic; + signal branch_int : std_logic; + + function isOverflowAdd ( + op1 : std_logic_vector; + op2 : std_logic_vector; + result : std_logic_vector) + return std_logic is + variable x : std_logic; + begin + x := '0'; + if op1(REGISTER_WIDTH-1) = '0' and op2(REGISTER_WIDTH-1) = '0' then + x := result(REGISTER_WIDTH-1); + end if; + if op1(REGISTER_WIDTH-1) = '1' and op2(REGISTER_WIDTH-1) = '1' then + x := not result(REGISTER_WIDTH-1); + end if; + return x; + end isOverflowAdd; + + function isOverflowSub ( + op1 : std_logic_vector; + op2 : std_logic_vector; + result : std_logic_vector) + return std_logic is + variable x : std_logic; + begin + x := '0'; + if op1(REGISTER_WIDTH-1) = '0' and op2(REGISTER_WIDTH-1) = '1' then + x := result(REGISTER_WIDTH-1); + end if; + if op1(REGISTER_WIDTH-1) = '1' and op2(REGISTER_WIDTH-1) = '0' then + x := not result(REGISTER_WIDTH-1); + end if; + + return x; + end isOverflowSub; begin -- ex_stage_rtl --- ex_mem_register <= ex_mem_register_int; + ex_mem_register <= ex_mem_register_int; --- process (clk, reset) --- begin -- process --- if reset = '0' then -- asynchronous reset (active low) --- ex_mem_register_int <= (others => (others => '0'));
--- ex_mem_register_next <= (others => (others => '0'));
--- elsif clk'event and clk = '1' then -- rising clock edge
--- ex_mem_register_int <= ex_mem_register_next;
--- end if;
--- end process;
+ output: process (clk, reset)
+ begin -- process
+ if reset = '0' then -- asynchronous reset (active low)
+ ex_mem_register_int.aluop1 <= (others => '0');
+ ex_mem_register_int.aluop2 <= (others => '0');
+ ex_mem_register_int.reg <= (others => '0');
+ ex_mem_register_int.alu <= (others => '0');
+ ex_mem_register_int.dreg_addr <= (others => '0');
+ ex_mem_register_int.lr <= (others => '0');
+ ex_mem_register_int.sr <= (others => '0');
+ elsif clk'event and clk = '1' then -- rising clock edge
+ -- if PIPELINE isn't stalled: update registers
+ if stall_in = '0' then
+ ex_mem_register_int <= ex_mem_register_next;
+ --id_ex_register <= id_ex_register_in;
+ clear_out <= clear_out_int;
+ branch <= branch_int;
+ end if;
+ end if;
+ end process output;
+
+ cond_check: process (id_ex_register, aluop1_int, aluop2_int)
+ begin -- process cond_check
+ execute <= '0';
+
+ case id_ex_register.cond is
+ when COND_UNCONDITIONAL =>
+ execute <= '1';
+ when COND_NOT_ZERO =>
+ if id_ex_register.sr(SR_ZERO_BIT) = '0' then
+ execute <= '1';
+ end if;
+ when COND_ZERO =>
+ if id_ex_register.sr(SR_ZERO_BIT) = '1' then
+ execute <= '1';
+ end if;
+ when COND_CARRY =>
+ if id_ex_register.sr(SR_CARRY_BIT) = '1' then
+ execute <= '1';
+ end if;
+ when COND_NEGATIVE =>
+ if id_ex_register.sr(SR_NEGATIVE_BIT) = '1' then
+ execute <= '1';
+ end if;
+ when COND_OVERFLOW =>
+ if id_ex_register.sr(SR_OVERFLOW_BIT) = '1' then
+ execute <= '1';
+ end if;
+ when COND_ZERO_NEGATIVE =>
+ if id_ex_register.sr(SR_ZERO_BIT) = '1' or
+ id_ex_register.sr(SR_ZERO_BIT) = '1' then
+ execute <= '1';
+ end if;
+ when others => null;
+ end case;
+ end process cond_check;
+
+ aluop: process (execute, aluop1_int, aluop2_int, clear_in)
+ begin -- process aluop
+ -- insert nop in pipeline if instruction is conditional and
+ -- condition is not met, or if pipeline is cleared
+ if execute = '0' or clear_in = '1' then
+ ex_mem_register_next.aluop1 <= (others => '0');
+ ex_mem_register_next.aluop2 <= (others => '0');
+ else
+ ex_mem_register_next.aluop1 <= aluop1_int;
+ ex_mem_register_next.aluop2 <= aluop2_int;
+ end if;
+ end process aluop;
+
+ alu: process (id_ex_register, ex_mem_register_next)
+ begin
+
+ ex_mem_register_next.alu <= (others => '0');
+ ex_mem_register_next.dreg_addr <= id_ex_register.rX_addr;
+ ex_mem_register_next.reg <= (others => '0');
+ ex_mem_register_next.lr <= (others => '0');
+ ex_mem_register_next.sr <= (others => '0');
+
+ aluop1_int(ALUOP1_LD_MEM_BIT) <= '0';
+ aluop1_int(ALUOP1_ST_MEM_BIT) <= '0';
+ aluop1_int(ALUOP1_WB_REG_BIT) <= '1';
+
+ aluop2_int <= (ALUOP2_LR_BIT => '0', ALUOP2_SR_BIT => '1', others => '0');
+
+ isLoadOp <= '0';
+ isJmpOp <= '0';
+
+ case id_ex_register.opcode is
+ -- load opcodes
+ when OPCODE_LD_IMM =>
+ ex_mem_register_next.alu <= x"00" & id_ex_register.immediate(7 downto 0);
+ isLoadOp <= '1';
+ when OPCODE_LD_IMM_HB =>
+ ex_mem_register_next.alu <= id_ex_register.rX or (id_ex_register.immediate(7 downto 0) & x"00");
+ isLoadOp <= '1';
+ when OPCODE_LD_DISP =>
+ ex_mem_register_next.alu <= id_ex_register.rY + id_ex_register.rZ;
+ aluop1_int(ALUOP1_LD_MEM_BIT) <= '1';
+ isLoadOp <= '1';
+ when OPCODE_LD_DISP_MS =>
+ ex_mem_register_next.alu <= id_ex_register.rY + id_ex_register.rZ;
+ aluop1_int(ALUOP1_LD_MEM_BIT) <= '1';
+ isLoadOp <= '1';
+ when OPCODE_LD_REG =>
+ ex_mem_register_next.alu <= id_ex_register.rY;
+ isLoadOp <= '1';
+
+ -- store opcodes
+ when OPCODE_ST_DISP =>
+ ex_mem_register_next.alu <= id_ex_register.rY + id_ex_register.rZ;
+ ex_mem_register_next.reg <= id_ex_register.rX;
+ aluop1_int(ALUOP1_ST_MEM_BIT) <= '1';
+ aluop2_int(ALUOP2_SR_BIT) <= '0';
+
+ -- arithmetic opcodes
+ when OPCODE_ADD =>
+ ex_mem_register_next.alu <= id_ex_register.rX + id_ex_register.rY;
+ ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= isOverflowAdd(id_ex_register.rX,
+ id_ex_register.rY,
+ ex_mem_register_next.alu);
+ when OPCODE_ADD_IMM =>
+ ex_mem_register_next.alu <= id_ex_register.rX + id_ex_register.immediate;
+ ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= isOverflowAdd(id_ex_register.rX,
+ id_ex_register.immediate,
+ ex_mem_register_next.alu);
+ when OPCODE_SUB =>
+ ex_mem_register_next.alu <= id_ex_register.rX - id_ex_register.rY;
+ ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= isOverflowSub(id_ex_register.rX,
+ id_ex_register.rY,
+ ex_mem_register_next.alu);
+ when OPCODE_SUB_IMM =>
+ ex_mem_register_next.alu <= id_ex_register.rX - id_ex_register.immediate;
+ ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= isOverflowSub(id_ex_register.rX,
+ id_ex_register.immediate,
+ ex_mem_register_next.alu);
+ when OPCODE_NEG =>
+ ex_mem_register_next.alu <= not id_ex_register.rY + x"0001";
+ when OPCODE_ALS =>
+ ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-2 downto 0) & "0";
+ ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= id_ex_register.rY(REGISTER_WIDTH-1) xor
+ id_ex_register.rY(REGISTER_WIDTH-2);
+ when OPCODE_ARS =>
+ ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-1) & id_ex_register.rY(REGISTER_WIDTH-1 downto 1);
+
+
+ -- logical opcodes
+ when OPCODE_AND =>
+ ex_mem_register_next.alu <= id_ex_register.rX and id_ex_register.rY;
+ when OPCODE_NOT =>
+ ex_mem_register_next.alu <= not id_ex_register.rY;
+ when OPCODE_EOR =>
+ ex_mem_register_next.alu <= id_ex_register.rX xor id_ex_register.rY;
+ when OPCODE_LS =>
+ ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-2 downto 0) & "0";
+ when OPCODE_RS =>
+ ex_mem_register_next.alu <= "0" & id_ex_register.rY(REGISTER_WIDTH-1 downto 1);
+
+ -- program control
+ when OPCODE_JMP =>
+ ex_mem_register_next.lr <= id_ex_register.pc;
+ ex_mem_register_next.dreg_addr <= PC_ADDR;
+ ex_mem_register_next.alu <= id_ex_register.rX;
+ aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
+ aluop2_int(ALUOP2_SR_BIT) <= '0';
+ aluop2_int(ALUOP2_LR_BIT) <= '1';
+ isJmpOp <= '1';
+
+ when OPCODE_NOP =>
+ aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
+ aluop2_int(ALUOP2_SR_BIT) <= '0';
+
+ when OPCODE_TST =>
+ aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
+ aluop2_int(ALUOP2_SR_BIT) <= '1';
+
+ when others =>
+ aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
+ aluop2_int(ALUOP2_SR_BIT) <= '0';
+
+ end case;
+ end process;
+
+ branch_logic: process (id_ex_register, isLoadOp, isJmpOp)
+ begin -- process branch_logic
+ branch_int <= '0';
+ clear_out_int <= '0';
+ if (id_ex_register.rX_addr = PC_ADDR and isLoadOp = '1') or (isJmpOp = '1') then
+ branch_int <= '1';
+ clear_out_int <= '1';
+ end if;
+ end process branch_logic;
end ex_stage_rtl;
1.3 rise/vhdl/rise_pack.vhd
http://www.opencores.org/cvsweb.shtml/rise/vhdl/rise_pack.vhd.diff?r1=1.2&r2=1.3
(In the diff below, changes in quantity of whitespace are not shown.)
Index: rise_pack.vhd
===================================================================
RCS file: /cvsroot/jlechner/rise/vhdl/rise_pack.vhd,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- rise_pack.vhd 13 Dec 2006 02:05:05 -0000 1.2
+++ rise_pack.vhd 31 Dec 2006 18:55:35 -0000 1.3
@@ -11,7 +11,7 @@
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-
+use IEEE.STD_LOGIC_ARITH.all;
package RISE_PACK is
@@ -31,6 +31,9 @@
constant IMMEDIATE_WIDTH : integer := ARCHITECTURE_WIDTH;
constant LOCK_WIDTH : integer := REGISTER_COUNT;
+ constant ALUOP1_WIDTH : integer := 3;
+ constant ALUOP2_WIDTH : integer := 3;
+
subtype PC_REGISTER_T is std_logic_vector(PC_WIDTH-1 downto 0);
subtype IR_REGISTER_T is std_logic_vector(IR_WIDTH-1 downto 0);
subtype SR_REGISTER_T is std_logic_vector(SR_WIDTH-1 downto 0);
@@ -45,6 +48,9 @@
subtype OPCODE_T is std_logic_vector(OPCODE_WIDTH-1 downto 0);
subtype COND_T is std_logic_vector(COND_WIDTH-1 downto 0);
+ subtype ALUOP1_T is std_logic_vector(ALUOP1_WIDTH-1 downto 0);
+ subtype ALUOP2_T is std_logic_vector(ALUOP2_WIDTH-1 downto 0);
+
--
constant SR_REGISTER_DI : INTEGER := 15;
constant SR_REGISTER_IP_MASK : INTEGER := 12;
@@ -56,13 +62,57 @@
constant RESET_SR_VALUE : PC_REGISTER_T := ( others => '0' );
constant COND_NONE : COND_T := "000";
+ constant PC_ADDR : REGISTER_ADDR_T := CONV_STD_LOGIC_VECTOR(14, REGISTER_ADDR_WIDTH);
+
-- RISE OPCODES --
+ -- load opcodes
constant OPCODE_LD_IMM : OPCODE_T := "10000";
+ constant OPCODE_LD_IMM_HB : OPCODE_T := "10010";
constant OPCODE_LD_DISP : OPCODE_T := "10100";
constant OPCODE_LD_DISP_MS : OPCODE_T := "11000";
constant OPCODE_LD_REG : OPCODE_T := "00001";
+
+ -- store opcodes
+ constant OPCODE_ST_DISP : OPCODE_T := "11100";
+
+ -- arithmethic opcodes
+ constant OPCODE_ADD : OPCODE_T := "00010";
+ constant OPCODE_ADD_IMM : OPCODE_T := "00011";
+ constant OPCODE_SUB : OPCODE_T := "00100";
+ constant OPCODE_SUB_IMM : OPCODE_T := "00101";
+ constant OPCODE_NEG : OPCODE_T := "00110";
+ constant OPCODE_ARS : OPCODE_T := "00111";
+ constant OPCODE_ALS : OPCODE_T := "01000";
+
+ -- logical opcodes
+ constant OPCODE_AND : OPCODE_T := "01001";
+ constant OPCODE_NOT : OPCODE_T := "01010";
+ constant OPCODE_EOR : OPCODE_T := "01011";
+ constant OPCODE_LS : OPCODE_T := "01100";
+ constant OPCODE_RS : OPCODE_T := "01101";
+
+ -- program control
+ constant OPCODE_JMP : OPCODE_T := "01110";
+
+ -- other
+ constant OPCODE_TST : OPCODE_T := "01111";
constant OPCODE_NOP : OPCODE_T := "00000";
+ -- CONDITION CODES --
+ constant COND_UNCONDITIONAL : COND_T := "000";
+ constant COND_NOT_ZERO : COND_T := "001";
+ constant COND_ZERO : COND_T := "010";
+ constant COND_CARRY : COND_T := "011";
+ constant COND_NEGATIVE : COND_T := "100";
+ constant COND_OVERFLOW : COND_T := "101";
+ constant COND_ZERO_NEGATIVE : COND_T := "110";
+
+ -- STATUS REGISTER BITS --
+ constant SR_ZERO_BIT : integer := 0;
+ constant SR_CARRY_BIT : integer := 1;
+ constant SR_NEGATIVE_BIT : integer := 2;
+ constant SR_OVERFLOW_BIT : integer := 3;
+
type IF_ID_REGISTER_T is record
pc : PC_REGISTER_T;
ir : IR_REGISTER_T;
@@ -80,18 +130,28 @@
immediate : IMMEDIATE_T;
end record;
+ -- bit positions for aluop1
+ constant ALUOP1_LD_MEM_BIT : integer := 0;
+ constant ALUOP1_ST_MEM_BIT : integer := 1;
+ constant ALUOP1_WB_REG_BIT : integer := 2;
+
+ -- bit positions for aluop2
+ constant ALUOP2_SR_BIT : integer := 0;
+ constant ALUOP2_LR_BIT : integer := 1;
+
type EX_MEM_REGISTER_T is record
- aluop1 : std_logic_vector(2 downto 0);
- aluop2 : std_logic_vector(2 downto 0);
+ aluop1 : ALUOP1_T;
+ aluop2 : ALUOP2_T;
reg : REGISTER_T;
alu : REGISTER_T;
dreg_addr : REGISTER_ADDR_T;
lr : PC_REGISTER_T;
+ sr : SR_REGISTER_T;
end record;
type MEM_WB_REGISTER_T is record
- aluop1 : std_logic_vector(2 downto 0);
- aluop2 : std_logic_vector(2 downto 0);
+ aluop1 : ALUOP1_T;
+ aluop2 : ALUOP2_T;
reg : REGISTER_T;
dreg_addr : REGISTER_ADDR_T;
lr : PC_REGISTER_T;
1.2 rise/vhdl/rlu.vhd
http://www.opencores.org/cvsweb.shtml/rise/vhdl/rlu.vhd.diff?r1=1.1&r2=1.2
(In the diff below, changes in quantity of whitespace are not shown.)
Index: rlu.vhd
===================================================================
RCS file: /cvsroot/jlechner/rise/vhdl/rlu.vhd,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- rlu.vhd 6 Dec 2006 22:41:04 -0000 1.1
+++ rlu.vhd 31 Dec 2006 18:55:35 -0000 1.2
@@ -9,8 +9,7 @@
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-use IEEE.STD_LOGIC_ARITH.all;
-
+use IEEE.numeric_std.all;
use WORK.RISE_PACK.all;
@@ -31,8 +30,33 @@
architecture rlu_rtl of rlu is
+ signal lock_register_int : LOCK_REGISTER_T;
+ signal lock_register_next : LOCK_REGISTER_T;
+
begin -- rlu_rtl
+ lock_register <= lock_register_int;
+
+ sync: process (clk, reset)
+ begin -- process
+ if reset = '0' then -- asynchronous reset (active low)
+ lock_register_int <= (others => '0');
+ elsif clk'event and clk = '1' then -- rising clock edge
+ lock_register_int <= lock_register_next;
+ end if;
+ end process;
+
+ async: process (lock_register_int, clear_reg_lock, set_reg_lock, reg_addr)
+ begin -- process async
+ lock_register_next <= lock_register_int;
+
+ if clear_reg_lock = '1' and set_reg_lock = '0' then
+ lock_register_next(to_integer(unsigned(reg_addr))) <= '0';
+ end if;
+ if set_reg_lock = '1' and clear_reg_lock = '0' then
+ lock_register_next(to_integer(unsigned(reg_addr))) <= '1';
+ end if;
+ end process async;
end rlu_rtl;
1.1 rise/vhdl/tb_ex_stage_unit.vhd
http://www.opencores.org/cvsweb.shtml/rise/vhdl/tb_ex_stage_unit.vhd?rev=1.1&content-type=text/x-cvsweb-markup
Index: tb_ex_stage_unit.vhd
===================================================================
-------------------------------------------------------------------------------
-- File: ex_stage.vhd
-- Author: Jakob Lechner, Urban Stadler, Harald Trinkl, Christian Walter
-- Created: 2006-11-29
-- Last updated: 2006-11-29
-- Description:
-- Execute stage
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_ARITH.all;
use work.rise_pack.all;
entity tb_ex_stage_unit_vhd is
end tb_ex_stage_unit_vhd;
architecture behavior of tb_ex_stage_unit_vhd is
-- component Declaration for the Unit Under Test (UUT)
component ex_stage is
port (
clk : in std_logic;
reset : in std_logic;
id_ex_register : in ID_EX_REGISTER_T;
ex_mem_register : out EX_MEM_REGISTER_T;
branch : out std_logic;
stall_in : in std_logic;
clear_in : in std_logic;
clear_out : out std_logic);
end component;
constant clk_period : time := 10 ns;
--inputs
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal id_ex_register : ID_EX_REGISTER_T;
signal stall_in : std_logic := '0';
signal clear_in : std_logic := '0';
--Outputs
signal ex_mem_register : EX_MEM_REGISTER_T;
signal branch : std_logic;
signal clear_out : std_logic;
begin
-- instantiate the Unit Under Test (UUT)
uut : ex_stage port map(
clk => clk,
reset => reset,
id_ex_register => id_ex_register,
ex_mem_register => ex_mem_register,
branch => branch,
stall_in => stall_in,
clear_in => clear_in,
clear_out => clear_out);
cg : process
begin
clk <= '1';
wait for clk_period/2;
clk <= '0';
wait for clk_period/2;
end process;
tb : process
begin
reset <= '0';
wait for 10 * clk_period;
reset <= '1';
id_ex_register.sr <= (others => '0');
id_ex_register.pc <= CONV_STD_LOGIC_VECTOR(3, PC_WIDTH);
id_ex_register.opcode <= OPCODE_NOP;
id_ex_register.cond <= COND_UNCONDITIONAL;
id_ex_register.rX_addr <= CONV_STD_LOGIC_VECTOR(2, REGISTER_ADDR_WIDTH);
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(0, REGISTER_WIDTH);
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(0, REGISTER_WIDTH);
id_ex_register.rZ <= CONV_STD_LOGIC_VECTOR(0, REGISTER_WIDTH);
id_ex_register.immediate <= CONV_STD_LOGIC_VECTOR(0, IMMEDIATE_WIDTH);
---------------------------------------------------------------------------
-- test computation results
---------------------------------------------------------------------------
-- load/store
wait for clk_period;
id_ex_register.opcode <= OPCODE_LD_IMM;
id_ex_register.immediate <= CONV_STD_LOGIC_VECTOR(1, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_LD_IMM_HB;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(1, REGISTER_WIDTH);
id_ex_register.immediate <= CONV_STD_LOGIC_VECTOR(2, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_LD_DISP;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(4, REGISTER_WIDTH);
id_ex_register.rZ <= CONV_STD_LOGIC_VECTOR(1, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_LD_DISP_MS;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(4, REGISTER_WIDTH);
id_ex_register.rZ <= CONV_STD_LOGIC_VECTOR(1, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_LD_REG;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(6, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_ST_DISP;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(4, REGISTER_WIDTH);
id_ex_register.rZ <= CONV_STD_LOGIC_VECTOR(1, REGISTER_WIDTH);
wait for clk_period;
-- arithmetic opcodes
id_ex_register.opcode <= OPCODE_ADD;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(8, REGISTER_WIDTH);
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(3, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_ADD;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(-8, REGISTER_WIDTH);
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(2, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_ADD_IMM;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(3, REGISTER_WIDTH);
id_ex_register.immediate <= CONV_STD_LOGIC_VECTOR(2, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_ADD_IMM;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(3, REGISTER_WIDTH);
id_ex_register.immediate <= CONV_STD_LOGIC_VECTOR(-2, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_SUB;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(4, REGISTER_WIDTH);
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(2, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_SUB;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(4, REGISTER_WIDTH);
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(6, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_SUB_IMM;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(-4, REGISTER_WIDTH);
id_ex_register.immediate <= CONV_STD_LOGIC_VECTOR(6, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_SUB_IMM;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(4, REGISTER_WIDTH);
id_ex_register.immediate <= CONV_STD_LOGIC_VECTOR(2, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_NEG;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(4, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_ARS;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(4, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_ALS;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(4, REGISTER_WIDTH);
-- als with overflow
wait for clk_period;
id_ex_register.opcode <= OPCODE_ALS;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(30000, REGISTER_WIDTH);
-- als with overflow
wait for clk_period;
id_ex_register.opcode <= OPCODE_ALS;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(-30000, REGISTER_WIDTH);
-- logical opcodes
wait for clk_period;
id_ex_register.opcode <= OPCODE_AND;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(4, REGISTER_WIDTH);
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(2, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_NOT;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(2, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_EOR;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(4, REGISTER_WIDTH);
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(2, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_LS;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(2, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.opcode <= OPCODE_RS;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(4, REGISTER_WIDTH);
-- other
wait for clk_period;
id_ex_register.opcode <= OPCODE_JMP;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(8, REGISTER_WIDTH);
---------------------------------------------------------------------------
-- test stall/clear
---------------------------------------------------------------------------
wait for clk_period;
stall_in <= '1';
id_ex_register.opcode <= OPCODE_JMP;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(8, REGISTER_WIDTH);
wait for clk_period;
stall_in <= '0';
id_ex_register.rX_addr <= CONV_STD_LOGIC_VECTOR(6, REGISTER_ADDR_WIDTH);
id_ex_register.opcode <= OPCODE_LD_REG;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(6, REGISTER_WIDTH);
wait for clk_period;
clear_in <= '1';
wait for clk_period;
clear_in <= '0';
---------------------------------------------------------------------------
-- branch (i.e. load instruction with PC as destination)
---------------------------------------------------------------------------
wait for clk_period;
id_ex_register.rX_addr <= PC_ADDR;
id_ex_register.opcode <= OPCODE_LD_REG;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(6, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.rX_addr <= CONV_STD_LOGIC_VECTOR(6, REGISTER_ADDR_WIDTH);
id_ex_register.opcode <= OPCODE_LD_REG;
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(6, REGISTER_WIDTH);
---------------------------------------------------------------------------
-- test conditionals
---------------------------------------------------------------------------
wait for clk_period;
id_ex_register.cond <= COND_ZERO;
id_ex_register.sr <= (SR_ZERO_BIT => '0', others => '0');
id_ex_register.opcode <= OPCODE_ADD;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(8, REGISTER_WIDTH);
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(3, REGISTER_WIDTH);
wait for clk_period;
id_ex_register.cond <= COND_UNCONDITIONAL;
id_ex_register.opcode <= OPCODE_ADD;
id_ex_register.rX <= CONV_STD_LOGIC_VECTOR(2, REGISTER_WIDTH);
id_ex_register.rY <= CONV_STD_LOGIC_VECTOR(2, REGISTER_WIDTH);
wait; -- will wait forever
end process;
end;
1.1 rise/vhdl/tb_rlu_unit.vhd
http://www.opencores.org/cvsweb.shtml/rise/vhdl/tb_rlu_unit.vhd?rev=1.1&content-type=text/x-cvsweb-markup
Index: tb_rlu_unit.vhd
===================================================================
-------------------------------------------------------------------------------
-- File: ex_stage.vhd
-- Author: Jakob Lechner, Urban Stadler, Harald Trinkl, Christian Walter
-- Created: 2006-12-31
-- Last updated: 2006-12-31
-- Description:
-- Testbench for RLU unit
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_ARITH.all;
use work.rise_pack.all;
entity tb_rlu_unit_vhd is
end tb_rlu_unit_vhd;
architecture behavior of tb_rlu_unit_vhd is
-- component Declaration for the Unit Under Test (UUT)
component rlu is
port (
clk : in std_logic;
reset : in std_logic;
lock_register : out LOCK_REGISTER_T;
clear_reg_lock : in std_logic;
set_reg_lock : in std_logic;
reg_addr : in REGISTER_ADDR_T);
end component;
constant clk_period : time := 10 ns;
--inputs
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal clear_reg_lock : std_logic := '0';
signal set_reg_lock : std_logic := '0';
signal reg_addr : REGISTER_ADDR_T;
--Outputs
signal lock_register : LOCK_REGISTER_T;
begin
-- instantiate the Unit Under Test (UUT)
uut : rlu port map(
clk => clk,
reset => reset,
lock_register => lock_register,
clear_reg_lock => clear_reg_lock,
set_reg_lock => set_reg_lock,
reg_addr => reg_addr);
cg : process
begin
clk <= '1';
wait for clk_period/2;
clk <= '0';
wait for clk_period/2;
end process;
tb : process
begin
reset <= '0';
wait for 10 * clk_period;
reset <= '1';
reg_addr <= CONV_STD_LOGIC_VECTOR(8, REGISTER_ADDR_WIDTH);
set_reg_lock <= '1';
wait for clk_period;
reg_addr <= CONV_STD_LOGIC_VECTOR(5, REGISTER_ADDR_WIDTH);
set_reg_lock <= '1';
wait for clk_period;
set_reg_lock <= '0';
reg_addr <= CONV_STD_LOGIC_VECTOR(8, REGISTER_ADDR_WIDTH);
clear_reg_lock <= '1';
wait for clk_period;
clear_reg_lock <= '0';
wait; -- will wait forever
end process;
end;
|
 |