aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/synth
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2022-12-18 08:35:43 +0100
committerTristan Gingold <tgingold@free.fr>2022-12-18 08:36:15 +0100
commitb4f09236ad974a133318d17a8487b36ebc35a78c (patch)
treea2d61d7039219d334b60d61946705c2d63de8264 /testsuite/synth
parent36c276363fa35f6856bbd44e7a37e712aaab2a1e (diff)
downloadghdl-b4f09236ad974a133318d17a8487b36ebc35a78c.tar.gz
ghdl-b4f09236ad974a133318d17a8487b36ebc35a78c.tar.bz2
ghdl-b4f09236ad974a133318d17a8487b36ebc35a78c.zip
testsuite/synth: add a test for #2273
Diffstat (limited to 'testsuite/synth')
-rw-r--r--testsuite/synth/issue2273/addsub_core_.vhd90
-rw-r--r--testsuite/synth/issue2273/addsub_core_struc.vhd116
-rw-r--r--testsuite/synth/issue2273/addsub_core_struc_cfg.vhd89
-rw-r--r--testsuite/synth/issue2273/addsub_cy_.vhd84
-rw-r--r--testsuite/synth/issue2273/addsub_cy_rtl.vhd94
-rw-r--r--testsuite/synth/issue2273/addsub_cy_rtl_cfg.vhd72
-rw-r--r--testsuite/synth/issue2273/addsub_ovcy_.vhd85
-rw-r--r--testsuite/synth/issue2273/addsub_ovcy_rtl.vhd138
-rw-r--r--testsuite/synth/issue2273/addsub_ovcy_rtl_cfg.vhd72
-rw-r--r--testsuite/synth/issue2273/alucore_.vhd92
-rw-r--r--testsuite/synth/issue2273/alucore_rtl.vhd161
-rw-r--r--testsuite/synth/issue2273/alucore_rtl_cfg.vhd71
-rw-r--r--testsuite/synth/issue2273/alumux_.vhd124
-rw-r--r--testsuite/synth/issue2273/alumux_rtl.vhd432
-rw-r--r--testsuite/synth/issue2273/alumux_rtl_cfg.vhd68
-rw-r--r--testsuite/synth/issue2273/comb_divider_.vhd82
-rw-r--r--testsuite/synth/issue2273/comb_divider_rtl.vhd114
-rw-r--r--testsuite/synth/issue2273/comb_divider_rtl_cfg.vhd72
-rw-r--r--testsuite/synth/issue2273/comb_mltplr_.vhd81
-rw-r--r--testsuite/synth/issue2273/comb_mltplr_rtl.vhd88
-rw-r--r--testsuite/synth/issue2273/comb_mltplr_rtl_cfg.vhd72
-rw-r--r--testsuite/synth/issue2273/control_fsm_.vhd124
-rw-r--r--testsuite/synth/issue2273/control_fsm_rtl.vhd2171
-rw-r--r--testsuite/synth/issue2273/control_fsm_rtl_cfg.vhd69
-rw-r--r--testsuite/synth/issue2273/control_mem_.vhd206
-rw-r--r--testsuite/synth/issue2273/control_mem_rtl.vhd1148
-rw-r--r--testsuite/synth/issue2273/control_mem_rtl_cfg.vhd71
-rw-r--r--testsuite/synth/issue2273/dcml_adjust_.vhd89
-rw-r--r--testsuite/synth/issue2273/dcml_adjust_rtl.vhd142
-rw-r--r--testsuite/synth/issue2273/dcml_adjust_rtl_cfg.vhd72
-rw-r--r--testsuite/synth/issue2273/mc8051.f45
-rw-r--r--testsuite/synth/issue2273/mc8051_alu_.vhd103
-rw-r--r--testsuite/synth/issue2273/mc8051_alu_struc.vhd197
-rw-r--r--testsuite/synth/issue2273/mc8051_alu_struc_cfg.vhd96
-rw-r--r--testsuite/synth/issue2273/mc8051_control_.vhd144
-rw-r--r--testsuite/synth/issue2273/mc8051_control_struc.vhd269
-rw-r--r--testsuite/synth/issue2273/mc8051_control_struc_cfg.vhd75
-rw-r--r--testsuite/synth/issue2273/mc8051_core_.vhd122
-rw-r--r--testsuite/synth/issue2273/mc8051_core_struc.vhd224
-rw-r--r--testsuite/synth/issue2273/mc8051_core_struc_cfg.vhd86
-rw-r--r--testsuite/synth/issue2273/mc8051_p.vhd864
-rw-r--r--testsuite/synth/issue2273/mc8051_siu_.vhd92
-rw-r--r--testsuite/synth/issue2273/mc8051_siu_rtl.vhd1202
-rw-r--r--testsuite/synth/issue2273/mc8051_siu_rtl_cfg.vhd71
-rw-r--r--testsuite/synth/issue2273/mc8051_tmrctr_.vhd96
-rw-r--r--testsuite/synth/issue2273/mc8051_tmrctr_rtl.vhd766
-rw-r--r--testsuite/synth/issue2273/mc8051_tmrctr_rtl_cfg.vhd71
-rwxr-xr-xtestsuite/synth/issue2273/testsuite.sh7
48 files changed, 10919 insertions, 0 deletions
diff --git a/testsuite/synth/issue2273/addsub_core_.vhd b/testsuite/synth/issue2273/addsub_core_.vhd
new file mode 100644
index 000000000..dbf682130
--- /dev/null
+++ b/testsuite/synth/issue2273/addsub_core_.vhd
@@ -0,0 +1,90 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: addsub_core_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.5 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Adder/Subtractor with carry/borrow, arbitrary data
+-- width, overflow, and nibble carry for decimal
+-- adjustment.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+library work;
+use work.mc8051_p.all;
+
+-----------------------------ENTITY DECLARATION--------------------------------
+
+entity addsub_core is
+
+ generic (DWIDTH : integer := 16); -- Data width of the ALU
+
+ port (opa_i : in std_logic_vector(DWIDTH-1 downto 0);
+ opb_i : in std_logic_vector(DWIDTH-1 downto 0);
+ addsub_i : in std_logic;
+ cy_i : in std_logic;
+
+ cy_o : out std_logic_vector((DWIDTH-1)/4 downto 0);
+ ov_o : out std_logic;
+ rslt_o : out std_logic_vector(DWIDTH-1 downto 0));
+
+end addsub_core;
+
diff --git a/testsuite/synth/issue2273/addsub_core_struc.vhd b/testsuite/synth/issue2273/addsub_core_struc.vhd
new file mode 100644
index 000000000..0e5cc57f9
--- /dev/null
+++ b/testsuite/synth/issue2273/addsub_core_struc.vhd
@@ -0,0 +1,116 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: addsub_core_struc.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Adder/Subtractor with carry/borrow, arbitrary data
+-- width, overflow, and nibble carry for decimal
+-- adjustment.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture struc of addsub_core is
+
+ type t_cy is array (1 to (DWIDTH/4)+1) of std_logic_vector(0 downto 0);
+
+ signal s_cy : t_cy;
+
+begin -- architecture structural
+
+ gen_smorequ_four : if (DWIDTH > 0 and DWIDTH <= 4) generate
+ addsub_ovcy_1 : addsub_ovcy
+ generic map (DWIDTH => DWIDTH)
+ port map (opa_i => opa_i,
+ opb_i => opb_i,
+ addsub_i => addsub_i,
+ cy_i => cy_i,
+ cy_o => cy_o(0),
+ ov_o => ov_o,
+ rslt_o => rslt_o);
+ end generate gen_smorequ_four;
+
+ s_cy(1)(0) <= cy_i;
+
+ gen_greater_four : if (DWIDTH > 4) generate
+ gen_addsub: for i in 1 to DWIDTH generate
+ gen_nibble_addsub: if (i mod 4 = 0) and i <= ((DWIDTH-1)/4)*4 generate
+ i_addsub_cy: addsub_cy
+ generic map (DWIDTH => 4)
+ port map (opa_i => opa_i(i-1 downto i-4),
+ opb_i => opb_i(i-1 downto i-4),
+ addsub_i => addsub_i,
+ cy_i => s_cy(i/4)(0),
+ cy_o => s_cy((i+4)/4)(0),
+ rslt_o => rslt_o(i-1 downto i-4));
+ cy_o(i/4-1) <= s_cy((i+4)/4)(0);
+ end generate gen_nibble_addsub;
+ gen_last_addsub: if (i = ((DWIDTH-1)/4)*4+1) generate
+ i_addsub_ovcy: addsub_ovcy
+ generic map (DWIDTH => DWIDTH-((DWIDTH-1)/4)*4)
+ port map (opa_i => opa_i(DWIDTH-1 downto i-1),
+ opb_i => opb_i(DWIDTH-1 downto i-1),
+ addsub_i => addsub_i,
+ cy_i => s_cy((DWIDTH-1)/4+1)(0),
+ cy_o => cy_o((DWIDTH-1)/4),
+ ov_o => ov_o,
+ rslt_o => rslt_o(DWIDTH-1 downto i-1));
+ end generate gen_last_addsub;
+ end generate gen_addsub;
+ end generate gen_greater_four;
+
+end struc;
diff --git a/testsuite/synth/issue2273/addsub_core_struc_cfg.vhd b/testsuite/synth/issue2273/addsub_core_struc_cfg.vhd
new file mode 100644
index 000000000..2c26e7362
--- /dev/null
+++ b/testsuite/synth/issue2273/addsub_core_struc_cfg.vhd
@@ -0,0 +1,89 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: addsub_core_struc_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Adder/Subtractor with carry/borrow, arbitrary data
+-- width, overflow, and nibble carry for decimal
+-- adjustment.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration addsub_core_struc_cfg of addsub_core is
+ for struc
+ for gen_smorequ_four
+ for addsub_ovcy_1 : addsub_ovcy
+ use configuration work.addsub_ovcy_rtl_cfg;
+ end for;
+ end for;
+ for gen_greater_four
+ for gen_addsub
+ for gen_nibble_addsub
+ for all : addsub_cy
+ use configuration work.addsub_cy_rtl_cfg;
+ end for;
+ end for;
+ for gen_last_addsub
+ for all : addsub_ovcy
+ use configuration work.addsub_ovcy_rtl_cfg;
+ end for;
+ end for;
+ end for;
+ end for;
+ end for;
+end addsub_core_struc_cfg;
diff --git a/testsuite/synth/issue2273/addsub_cy_.vhd b/testsuite/synth/issue2273/addsub_cy_.vhd
new file mode 100644
index 000000000..507fd4596
--- /dev/null
+++ b/testsuite/synth/issue2273/addsub_cy_.vhd
@@ -0,0 +1,84 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: addsub_cy_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Adder/Subtractor with carry/borrow and arbitrary
+-- data width.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+-----------------------------ENTITY DECLARATION--------------------------------
+
+entity addsub_cy is
+
+ generic (DWIDTH : integer := 4);
+
+ port (opa_i : in std_logic_vector(DWIDTH-1 downto 0); -- Operand A
+ opb_i : in std_logic_vector(DWIDTH-1 downto 0); -- Operand B
+ addsub_i : in std_logic; -- Add or subtract command
+ cy_i : in std_logic; -- Carry input
+ cy_o : out std_logic; -- Carry/borrow bit
+ rslt_o : out std_logic_vector(DWIDTH-1 downto 0)); -- Result
+
+end addsub_cy;
+
diff --git a/testsuite/synth/issue2273/addsub_cy_rtl.vhd b/testsuite/synth/issue2273/addsub_cy_rtl.vhd
new file mode 100644
index 000000000..dbbf8ea61
--- /dev/null
+++ b/testsuite/synth/issue2273/addsub_cy_rtl.vhd
@@ -0,0 +1,94 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: addsub_cy_rtl.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Adder/Subtractor with carry/borrow and arbitrary
+-- data width.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture rtl of addsub_cy is
+
+begin
+
+ -- purpose: Simple adder/subtractor with carry/borrow
+ -- type : combinational
+ -- inputs : opa_i, opb_i, addsub_i
+ -- outputs: cy_o, rslt_o
+ p_addsub: process (opa_i, opb_i, addsub_i, cy_i)
+ variable v_a : unsigned(DWIDTH downto 0);
+ variable v_b : unsigned(DWIDTH downto 0);
+ variable v_result : std_logic_vector(DWIDTH+1 downto 0);
+ begin -- process p_addsub
+ v_a(DWIDTH downto 1) := unsigned(opa_i);
+ v_b(DWIDTH downto 1) := unsigned(opb_i);
+ if addsub_i = '1' then
+ v_a(0) := '1';
+ v_b(0) := cy_i;
+ v_result := conv_unsigned(v_a,DWIDTH+2) + v_b;
+ else
+ v_a(0) := '0';
+ v_b(0) := cy_i;
+ v_result := conv_unsigned(v_a,DWIDTH+2) - v_b;
+ end if;
+ cy_o <= v_result(DWIDTH+1);
+ rslt_o <= v_result(DWIDTH downto 1);
+ end process p_addsub;
+
+end rtl;
diff --git a/testsuite/synth/issue2273/addsub_cy_rtl_cfg.vhd b/testsuite/synth/issue2273/addsub_cy_rtl_cfg.vhd
new file mode 100644
index 000000000..6dd200b6a
--- /dev/null
+++ b/testsuite/synth/issue2273/addsub_cy_rtl_cfg.vhd
@@ -0,0 +1,72 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: addsub_cy_rtl_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Adder/Subtractor with carry/borrow and arbitrary
+-- data width.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration addsub_cy_rtl_cfg of addsub_cy is
+
+ for rtl
+
+ end for;
+
+end addsub_cy_rtl_cfg;
diff --git a/testsuite/synth/issue2273/addsub_ovcy_.vhd b/testsuite/synth/issue2273/addsub_ovcy_.vhd
new file mode 100644
index 000000000..8b9d0314a
--- /dev/null
+++ b/testsuite/synth/issue2273/addsub_ovcy_.vhd
@@ -0,0 +1,85 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: addsub_ovcy_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Adder/Subtractor with carry/borrow and arbitrary data
+-- width and overflow flag.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+-----------------------------ENTITY DECLARATION--------------------------------
+
+entity addsub_ovcy is
+
+ generic (DWIDTH : integer := 4);
+
+ port (opa_i : in std_logic_vector(DWIDTH-1 downto 0); -- Operand A
+ opb_i : in std_logic_vector(DWIDTH-1 downto 0); -- Operand B
+ addsub_i : in std_logic; -- Add or subtract command
+ cy_i : in std_logic; -- Carry input
+ cy_o : out std_logic; -- Carry/borrow bit
+ ov_o : out std_logic; -- Overflow flag
+ rslt_o : out std_logic_vector(DWIDTH-1 downto 0)); -- Result
+
+end addsub_ovcy;
+
diff --git a/testsuite/synth/issue2273/addsub_ovcy_rtl.vhd b/testsuite/synth/issue2273/addsub_ovcy_rtl.vhd
new file mode 100644
index 000000000..48740003d
--- /dev/null
+++ b/testsuite/synth/issue2273/addsub_ovcy_rtl.vhd
@@ -0,0 +1,138 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: addsub_ovcy_rtl.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Adder/Subtractor with carry/borrow and arbitrary data
+-- width and overflow flag.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture rtl of addsub_ovcy is
+
+begin
+
+ gen_equal_one: if (DWIDTH = 1) generate
+ -- purpose: Simple adder/subtractor with carry/borrow and overflow
+ -- type : combinational
+ -- inputs : opa_i, opb_i, addsub_i, cy_i
+ -- outputs: cy_o, rslt_o
+ p_addsub_ov: process (opa_i, opb_i, addsub_i, cy_i)
+ variable v_la : unsigned(1 downto 0);
+ variable v_lb : unsigned(1 downto 0);
+ variable v_lresult : std_logic_vector(2 downto 0);
+ begin -- process p_addsub
+ v_la(1) := opa_i(DWIDTH-1);
+ v_lb(1) := opb_i(DWIDTH-1);
+ if addsub_i = '1' then
+ v_la(0) := '1';
+ v_lb(0) := cy_i;
+ v_lresult := conv_unsigned(v_la,3) + unsigned(v_lb);
+ else
+ v_la(0) := '0';
+ v_lb(0) := cy_i;
+ v_lresult := conv_unsigned(v_la,3) - unsigned(v_lb);
+ end if;
+ cy_o <= v_lresult(2);
+ ov_o <= (cy_i and not(v_lresult(2))) or
+ (v_lresult(2) and not(cy_i));
+ rslt_o(DWIDTH-1) <= v_lresult(1);
+ end process p_addsub_ov;
+ end generate gen_equal_one;
+
+ gen_greater_one: if (DWIDTH > 1) generate
+ -- purpose: Simple adder/subtractor with carry/borrow and overflow
+ -- type : combinational
+ -- inputs : opa_i, opb_i, addsub_i, cy_i
+ -- outputs: cy_o, rslt_o
+ p_addsub_ov: process (opa_i, opb_i, addsub_i, cy_i)
+ variable v_a : unsigned(DWIDTH-1 downto 0);
+ variable v_b : unsigned(DWIDTH-1 downto 0);
+ variable v_result : std_logic_vector(DWIDTH downto 0);
+ variable v_la : unsigned(1 downto 0);
+ variable v_lb : unsigned(1 downto 0);
+ variable v_lresult : std_logic_vector(2 downto 0);
+ begin -- process p_addsub
+ v_a(DWIDTH-1 downto 1) := unsigned(opa_i(DWIDTH-2 downto 0));
+ v_b(DWIDTH-1 downto 1) := unsigned(opb_i(DWIDTH-2 downto 0));
+ v_la(1) := opa_i(DWIDTH-1);
+ v_lb(1) := opb_i(DWIDTH-1);
+ if addsub_i = '1' then
+ v_a(0) := '1';
+ v_b(0) := cy_i;
+ v_result := conv_unsigned(v_a,DWIDTH+1) + unsigned(v_b);
+ v_la(0) := '1';
+ v_lb(0) := v_result(DWIDTH);
+ v_lresult := conv_unsigned(v_la,3) + unsigned(v_lb);
+ else
+ v_a(0) := '0';
+ v_b(0) := cy_i;
+ v_result := conv_unsigned(v_a,DWIDTH+1) - unsigned(v_b);
+ v_la(0) := '0';
+ v_lb(0) := v_result(DWIDTH);
+ v_lresult := conv_unsigned(v_la,3) - unsigned(v_lb);
+ end if;
+ cy_o <= v_lresult(2);
+ ov_o <= (v_result(DWIDTH) and not(v_lresult(2))) or
+ (v_lresult(2) and not(v_result(DWIDTH)));
+ rslt_o(DWIDTH-2 downto 0) <= v_result(DWIDTH-1 downto 1);
+ rslt_o(DWIDTH-1) <= v_lresult(1);
+ end process p_addsub_ov;
+ end generate gen_greater_one;
+
+end rtl;
diff --git a/testsuite/synth/issue2273/addsub_ovcy_rtl_cfg.vhd b/testsuite/synth/issue2273/addsub_ovcy_rtl_cfg.vhd
new file mode 100644
index 000000000..b38433ae2
--- /dev/null
+++ b/testsuite/synth/issue2273/addsub_ovcy_rtl_cfg.vhd
@@ -0,0 +1,72 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: addsub_ovcy_rtl_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Adder/Subtractor with carry/borrow and arbitrary data
+-- width and overflow flag.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration addsub_ovcy_rtl_cfg of addsub_ovcy is
+
+ for rtl
+
+ end for;
+
+end addsub_ovcy_rtl_cfg;
diff --git a/testsuite/synth/issue2273/alucore_.vhd b/testsuite/synth/issue2273/alucore_.vhd
new file mode 100644
index 000000000..68b5a3474
--- /dev/null
+++ b/testsuite/synth/issue2273/alucore_.vhd
@@ -0,0 +1,92 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: alucore_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: This unit performs simple logical operations.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+library work;
+use work.mc8051_p.all;
+
+-----------------------------ENTITY DECLARATION--------------------------------
+
+entity alucore is
+
+ generic (DWIDTH : integer := 8); -- Data width of the ALU
+
+ port (op_a_i : in std_logic_vector(DWIDTH-1 downto 0);
+ op_b_i : in std_logic_vector(DWIDTH-1 downto 0);
+ alu_cmd_i : in std_logic_vector(3 downto 0);
+ cy_i : in std_logic_vector((DWIDTH-1)/4 downto 0);
+ cy_o : out std_logic_vector((DWIDTH-1)/4 downto 0);
+ result_o : out std_logic_vector(DWIDTH-1 downto 0));
+
+end alucore;
+
+-- op_a_i....... operand A
+-- op_b_i....... operand B
+-- alu_cmd_i.... command for the ALU core
+-- cy_i......... carry flags (MSB is CY, rest is AC)
+
+-- cy_o......... resulting carry out (MSB is CY, rest is AC)
+-- result_o..... result
diff --git a/testsuite/synth/issue2273/alucore_rtl.vhd b/testsuite/synth/issue2273/alucore_rtl.vhd
new file mode 100644
index 000000000..1ff5dc851
--- /dev/null
+++ b/testsuite/synth/issue2273/alucore_rtl.vhd
@@ -0,0 +1,161 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: alucore_rtl.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.5 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: This unit performs simple logical operations.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture rtl of alucore is
+
+ constant LAND : std_logic_vector(3 downto 0) := "0011";
+ constant LOR : std_logic_vector(3 downto 0) := "0101";
+ constant LXOR : std_logic_vector(3 downto 0) := "0110";
+ constant RL : std_logic_vector(3 downto 0) := "0111";
+ constant RLC : std_logic_vector(3 downto 0) := "1000";
+ constant RR : std_logic_vector(3 downto 0) := "1001";
+ constant RRC : std_logic_vector(3 downto 0) := "1010";
+ constant COMP : std_logic_vector(3 downto 0) := "1011";
+ constant INV : std_logic_vector(3 downto 0) := "1100";
+
+begin -- architecture structural
+
+ p_alu: process (alu_cmd_i, op_a_i, op_b_i, cy_i)
+
+ begin
+
+ case alu_cmd_i is
+-------------------------------------------------------------------------------
+ when LAND => -- op_a_i and op_b_i
+ result_o <= op_a_i and op_b_i;
+ cy_o <= cy_i;
+-------------------------------------------------------------------------------
+ when LOR => -- op_a_i or op_b_i
+ result_o <= op_a_i or op_b_i;
+ cy_o <= cy_i;
+-------------------------------------------------------------------------------
+ when LXOR => -- op_a_i xor op_b_i
+ result_o <= op_a_i xor op_b_i;
+ cy_o <= cy_i;
+-------------------------------------------------------------------------------
+ when RL => -- rotate left op_a_i
+ if DWIDTH > 1 then
+ result_o(DWIDTH-1 downto 1) <= op_a_i(DWIDTH-2 downto 0);
+ result_o(0) <= op_a_i(DWIDTH-1);
+ else
+ result_o <= op_a_i;
+ end if;
+ cy_o <= cy_i;
+-------------------------------------------------------------------------------
+ when RLC => -- rotate left op_a_i with CY
+ if DWIDTH > 1 then
+ result_o(DWIDTH-1 downto 1) <= op_a_i(DWIDTH-2 downto 0);
+ result_o(0) <= cy_i((DWIDTH-1)/4);
+ else
+ result_o(0) <= cy_i((DWIDTH-1)/4);
+ end if;
+ cy_o <= cy_i;
+ cy_o((DWIDTH-1)/4) <= op_a_i(DWIDTH-1);
+-------------------------------------------------------------------------------
+ when RR => -- rotate right op_a_i
+ if DWIDTH > 1 then
+ result_o(DWIDTH-2 downto 0) <= op_a_i(DWIDTH-1 downto 1);
+ result_o(DWIDTH-1) <= op_a_i(0);
+ else
+ result_o <= op_a_i;
+ end if;
+ cy_o <= cy_i;
+-------------------------------------------------------------------------------
+ when RRC => -- rotate right op_a_i with CY
+ if DWIDTH > 1 then
+ result_o(DWIDTH-2 downto 0) <= op_a_i(DWIDTH-1 downto 1);
+ result_o(DWIDTH-1) <= cy_i((DWIDTH-1)/4);
+ else
+ result_o(0) <= cy_i((DWIDTH-1)/4);
+ end if;
+ cy_o <= cy_i;
+ cy_o((DWIDTH-1)/4) <= op_a_i(0);
+-------------------------------------------------------------------------------
+ when COMP => -- Compare op_a_i with op_b_i
+ if op_a_i = op_b_i then
+ result_o <= (others => '0');
+ else
+ result_o <= (others => '1');
+ end if;
+ cy_o <= cy_i;
+ if op_a_i < op_b_i then
+ cy_o((DWIDTH-1)/4) <= '1';
+ else
+ cy_o((DWIDTH-1)/4) <= '0';
+ end if;
+-------------------------------------------------------------------------------
+ when INV => -- invert op_a_i
+ result_o <= not(op_a_i);
+ cy_o <= cy_i;
+-------------------------------------------------------------------------------
+ when others => -- turn unit off
+ result_o <= (others => '0');
+ cy_o <= (others => '0');
+-------------------------------------------------------------------------------
+ end case;
+
+ end process p_alu;
+
+end rtl;
+
diff --git a/testsuite/synth/issue2273/alucore_rtl_cfg.vhd b/testsuite/synth/issue2273/alucore_rtl_cfg.vhd
new file mode 100644
index 000000000..3dfff35e9
--- /dev/null
+++ b/testsuite/synth/issue2273/alucore_rtl_cfg.vhd
@@ -0,0 +1,71 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: alucore_rtl_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: This unit performs simple logical operations.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration alucore_rtl_cfg of alucore is
+
+ for rtl
+
+ end for;
+
+end alucore_rtl_cfg;
diff --git a/testsuite/synth/issue2273/alumux_.vhd b/testsuite/synth/issue2273/alumux_.vhd
new file mode 100644
index 000000000..5f5742f2d
--- /dev/null
+++ b/testsuite/synth/issue2273/alumux_.vhd
@@ -0,0 +1,124 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: alumux_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.6 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Select data path according to the actual command.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+library work;
+use work.mc8051_p.all;
+
+-----------------------------ENTITY DECLARATION--------------------------------
+
+
+entity alumux is
+
+ generic (DWIDTH : integer := 8); -- Data width of the ALU
+
+ port (
+ -- inputs from control unit
+ rom_data_i : in std_logic_vector(DWIDTH-1 downto 0);
+ ram_data_i : in std_logic_vector(DWIDTH-1 downto 0);
+ acc_i : in std_logic_vector(DWIDTH-1 downto 0);
+ cmd_i : in std_logic_vector(5 downto 0);
+ cy_i : in std_logic_vector((DWIDTH-1)/4 downto 0);
+ ov_i : in std_logic;
+ -- outputs to control unit
+ cy_o : out std_logic_vector((DWIDTH-1)/4 downto 0);
+ ov_o : out std_logic;
+ result_a_o : out std_logic_vector(DWIDTH-1 downto 0);
+ result_b_o : out std_logic_vector(DWIDTH-1 downto 0);
+ -- inputs from alu core
+ result_i : in std_logic_vector(DWIDTH-1 downto 0);
+ new_cy_i : in std_logic_vector((DWIDTH-1)/4 downto 0);
+ -- inputs from addsub unit
+ addsub_rslt_i : in std_logic_vector(DWIDTH-1 downto 0);
+ addsub_cy_i : in std_logic_vector((DWIDTH-1)/4 downto 0);
+ addsub_ov_i : in std_logic;
+ -- outputs to alu core
+ op_a_o : out std_logic_vector(DWIDTH-1 downto 0);
+ op_b_o : out std_logic_vector(DWIDTH-1 downto 0);
+ alu_cmd_o : out std_logic_vector(3 downto 0);
+ -- outputs to addsub unit
+ opa_o : out std_logic_vector(DWIDTH-1 downto 0);
+ opb_o : out std_logic_vector(DWIDTH-1 downto 0);
+ addsub_o : out std_logic;
+ addsub_cy_o : out std_logic;
+ -- outputs to divider unit
+ dvdnd_o : out std_logic_vector(DWIDTH-1 downto 0);
+ dvsor_o : out std_logic_vector(DWIDTH-1 downto 0);
+ -- inputs from divider
+ qutnt_i : in std_logic_vector(DWIDTH-1 downto 0);
+ rmndr_i : in std_logic_vector(DWIDTH-1 downto 0);
+ -- outputs to multiplier
+ mltplcnd_o : out std_logic_vector(DWIDTH-1 downto 0);
+ mltplctr_o : out std_logic_vector(DWIDTH-1 downto 0);
+ -- inputs from multiplier
+ product_i : in std_logic_vector((DWIDTH*2)-1 downto 0);
+ -- outputs to decimal adjustement
+ dcml_data_o : out std_logic_vector(DWIDTH-1 downto 0);
+ -- inputs from decimal adjustement
+ dcml_data_i : in std_logic_vector(DWIDTH-1 downto 0);
+ dcml_cy_i : in std_logic);
+
+end alumux;
diff --git a/testsuite/synth/issue2273/alumux_rtl.vhd b/testsuite/synth/issue2273/alumux_rtl.vhd
new file mode 100644
index 000000000..ab698847f
--- /dev/null
+++ b/testsuite/synth/issue2273/alumux_rtl.vhd
@@ -0,0 +1,432 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: alumux_rtl.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.6 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Select data path according to the actual command.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture rtl of alumux is
+
+ constant DA : std_logic_vector(5 downto 0) := "100000";
+ constant ADD_ACC_RAM : std_logic_vector(5 downto 0) := "100001";
+ constant ADD_ACC_ROM : std_logic_vector(5 downto 0) := "100010";
+ constant ADDC_ACC_RAM : std_logic_vector(5 downto 0) := "100011";
+ constant ADDC_ACC_ROM : std_logic_vector(5 downto 0) := "100100";
+ constant AND_ACC_RAM : std_logic_vector(5 downto 0) := "100101";
+ constant AND_ACC_ROM : std_logic_vector(5 downto 0) := "100110";
+ constant AND_RAM_ROM : std_logic_vector(5 downto 0) := "100111";
+ constant SUB_ACC_RAM : std_logic_vector(5 downto 0) := "101000";
+ constant SUB_ACC_ROM : std_logic_vector(5 downto 0) := "101001";
+ constant MUL_ACC_RAM : std_logic_vector(5 downto 0) := "101010";
+ constant DIV_ACC_RAM : std_logic_vector(5 downto 0) := "101011";
+ constant OR_RAM_ACC : std_logic_vector(5 downto 0) := "101100";
+ constant OR_ROM_ACC : std_logic_vector(5 downto 0) := "101101";
+ constant OR_ROM_RAM : std_logic_vector(5 downto 0) := "101110";
+ constant XOR_RAM_ACC : std_logic_vector(5 downto 0) := "101111";
+ constant XOR_ROM_ACC : std_logic_vector(5 downto 0) := "110000";
+ constant XOR_ROM_RAM : std_logic_vector(5 downto 0) := "110001";
+ constant RL_ACC : std_logic_vector(5 downto 0) := "110010";
+ constant RLC_ACC : std_logic_vector(5 downto 0) := "110011";
+ constant RR_ACC : std_logic_vector(5 downto 0) := "110100";
+ constant RRC_ACC : std_logic_vector(5 downto 0) := "110101";
+ constant INV_ACC : std_logic_vector(5 downto 0) := "110110";
+ constant INV_RAM : std_logic_vector(5 downto 0) := "110111";
+ constant DEC_ACC : std_logic_vector(5 downto 0) := "111000";
+ constant DEC_RAM : std_logic_vector(5 downto 0) := "111001";
+ constant COMP_RAM_ACC : std_logic_vector(5 downto 0) := "111010";
+ constant COMP_ROM_ACC : std_logic_vector(5 downto 0) := "111011";
+ constant COMP_ROM_RAM : std_logic_vector(5 downto 0) := "111100";
+ constant INC_ACC : std_logic_vector(5 downto 0) := "111110";
+ constant INC_RAM : std_logic_vector(5 downto 0) := "111111";
+
+ constant NOP : std_logic_vector(3 downto 0) := "0000";
+ constant LAND : std_logic_vector(3 downto 0) := "0011";
+ constant LOR : std_logic_vector(3 downto 0) := "0101";
+ constant LXOR : std_logic_vector(3 downto 0) := "0110";
+ constant RL : std_logic_vector(3 downto 0) := "0111";
+ constant RLC : std_logic_vector(3 downto 0) := "1000";
+ constant RR : std_logic_vector(3 downto 0) := "1001";
+ constant RRC : std_logic_vector(3 downto 0) := "1010";
+ constant COMP : std_logic_vector(3 downto 0) := "1011";
+ constant INV : std_logic_vector(3 downto 0) := "1100";
+
+begin
+
+ -- Multiplex the input data and generate the command for the alu core.
+ p_alucore_mux : process (rom_data_i,
+ ram_data_i,
+ acc_i,
+ cmd_i)
+ begin
+ case cmd_i is
+ when AND_ACC_RAM =>
+ alu_cmd_o <= LAND;
+ op_a_o <= acc_i;
+ op_b_o <= ram_data_i;
+ when AND_ACC_ROM =>
+ alu_cmd_o <= LAND;
+ op_a_o <= acc_i;
+ op_b_o <= rom_data_i;
+ when AND_RAM_ROM =>
+ alu_cmd_o <= LAND;
+ op_a_o <= ram_data_i;
+ op_b_o <= rom_data_i;
+ when OR_RAM_ACC =>
+ alu_cmd_o <= LOR;
+ op_a_o <= acc_i;
+ op_b_o <= ram_data_i;
+ when OR_ROM_ACC =>
+ alu_cmd_o <= LOR;
+ op_a_o <= acc_i;
+ op_b_o <= rom_data_i;
+ when OR_ROM_RAM =>
+ alu_cmd_o <= LOR;
+ op_a_o <= rom_data_i;
+ op_b_o <= ram_data_i;
+ when XOR_RAM_ACC =>
+ alu_cmd_o <= LXOR;
+ op_a_o <= acc_i;
+ op_b_o <= ram_data_i;
+ when XOR_ROM_ACC =>
+ alu_cmd_o <= LXOR;
+ op_a_o <= acc_i;
+ op_b_o <= rom_data_i;
+ when XOR_ROM_RAM =>
+ alu_cmd_o <= LXOR;
+ op_a_o <= rom_data_i;
+ op_b_o <= ram_data_i;
+ when RL_ACC =>
+ alu_cmd_o <= RL;
+ op_a_o <= acc_i;
+ op_b_o <= ( others => '0' );
+ when RLC_ACC =>
+ alu_cmd_o <= RLC;
+ op_a_o <= acc_i;
+ op_b_o <= ( others => '0' );
+ when RR_ACC =>
+ alu_cmd_o <= RR;
+ op_a_o <= acc_i;
+ op_b_o <= ( others => '0' );
+ when RRC_ACC =>
+ alu_cmd_o <= RRC;
+ op_a_o <= acc_i;
+ op_b_o <= ( others => '0' );
+ when INV_ACC =>
+ alu_cmd_o <= INV;
+ op_a_o <= acc_i;
+ op_b_o <= ( others => '0' );
+ when INV_RAM =>
+ alu_cmd_o <= INV;
+ op_a_o <= ram_data_i;
+ op_b_o <= ( others => '0' );
+ when COMP_RAM_ACC =>
+ alu_cmd_o <= COMP;
+ op_a_o <= acc_i;
+ op_b_o <= ram_data_i;
+ when COMP_ROM_ACC =>
+ alu_cmd_o <= COMP;
+ op_a_o <= acc_i;
+ op_b_o <= rom_data_i;
+ when COMP_ROM_RAM =>
+ alu_cmd_o <= COMP;
+ op_a_o <= ram_data_i;
+ op_b_o <= rom_data_i;
+ when others =>
+ alu_cmd_o <= NOP;
+ op_a_o <= ( others => '0' );
+ op_b_o <= ( others => '0' );
+ end case;
+ end process p_alucore_mux;
+
+ -- Multiplex the input data for all the functions not included in the
+ -- alu core.
+ p_ext_mux : process (ram_data_i,
+ rom_data_i,
+ acc_i,
+ cy_i,
+ cmd_i)
+ begin
+ case cmd_i is
+ when DA =>
+ dcml_data_o <= acc_i;
+ mltplcnd_o <= ( others => '0' );
+ mltplctr_o <= ( others => '0' );
+ dvdnd_o <= ( others => '0' );
+ dvsor_o <= ( others => '0' );
+ addsub_o <= '0';
+ addsub_cy_o <= '0';
+ opa_o <= ( others => '0' );
+ opb_o <= ( others => '0' );
+ when DIV_ACC_RAM =>
+ dcml_data_o <= ( others => '0' );
+ mltplcnd_o <= ( others => '0' );
+ mltplctr_o <= ( others => '0' );
+ dvdnd_o <= acc_i;
+ dvsor_o <= ram_data_i;
+ addsub_o <= '0';
+ addsub_cy_o <= '0';
+ opa_o <= ( others => '0' );
+ opb_o <= ( others => '0' );
+ when MUL_ACC_RAM =>
+ dcml_data_o <= ( others => '0' );
+ mltplcnd_o <= acc_i;
+ mltplctr_o <= ram_data_i;
+ dvdnd_o <= ( others => '0' );
+ dvsor_o <= ( others => '0' );
+ addsub_o <= '0';
+ addsub_cy_o <= '0';
+ opa_o <= ( others => '0' );
+ opb_o <= ( others => '0' );
+ when INC_ACC =>
+ dcml_data_o <= ( others => '0' );
+ mltplcnd_o <= ( others => '0' );
+ mltplctr_o <= ( others => '0' );
+ dvdnd_o <= ( others => '0' );
+ dvsor_o <= ( others => '0' );
+ addsub_o <= '1';
+ addsub_cy_o <= '0';
+ opa_o <= acc_i;
+ opb_o <= std_logic_vector(conv_unsigned(1, DWIDTH));
+ when INC_RAM =>
+ dcml_data_o <= ( others => '0' );
+ mltplcnd_o <= ( others => '0' );
+ mltplctr_o <= ( others => '0' );
+ dvdnd_o <= ( others => '0' );
+ dvsor_o <= ( others => '0' );
+ addsub_o <= '1';
+ addsub_cy_o <= '0';
+ opa_o <= ram_data_i;
+ opb_o <= std_logic_vector(conv_unsigned(1, DWIDTH));
+ when DEC_ACC =>
+ dcml_data_o <= ( others => '0' );
+ mltplcnd_o <= ( others => '0' );
+ mltplctr_o <= ( others => '0' );
+ dvdnd_o <= ( others => '0' );
+ dvsor_o <= ( others => '0' );
+ addsub_o <= '0';
+ addsub_cy_o <= '0';
+ opa_o <= acc_i;
+ opb_o <= std_logic_vector(conv_unsigned(1, DWIDTH));
+ when DEC_RAM =>
+ dcml_data_o <= ( others => '0' );
+ mltplcnd_o <= ( others => '0' );
+ mltplctr_o <= ( others => '0' );
+ dvdnd_o <= ( others => '0' );
+ dvsor_o <= ( others => '0' );
+ addsub_o <= '0';
+ addsub_cy_o <= '0';
+ opa_o <= ram_data_i;
+ opb_o <= std_logic_vector(conv_unsigned(1, DWIDTH));
+ when SUB_ACC_RAM =>
+ dcml_data_o <= ( others => '0' );
+ mltplcnd_o <= ( others => '0' );
+ mltplctr_o <= ( others => '0' );
+ dvdnd_o <= ( others => '0' );
+ dvsor_o <= ( others => '0' );
+ addsub_o <= '0';
+ addsub_cy_o <= cy_i((DWIDTH-1)/4);
+ opa_o <= acc_i;
+ opb_o <= ram_data_i;
+ when SUB_ACC_ROM =>
+ dcml_data_o <= ( others => '0' );
+ mltplcnd_o <= ( others => '0' );
+ mltplctr_o <= ( others => '0' );
+ dvdnd_o <= ( others => '0' );
+ dvsor_o <= ( others => '0' );
+ addsub_o <= '0';
+ addsub_cy_o <= cy_i((DWIDTH-1)/4);
+ opa_o <= acc_i;
+ opb_o <= rom_data_i;
+ when ADD_ACC_RAM =>
+ dcml_data_o <= ( others => '0' );
+ mltplcnd_o <= ( others => '0' );
+ mltplctr_o <= ( others => '0' );
+ dvdnd_o <= ( others => '0' );
+ dvsor_o <= ( others => '0' );
+ addsub_o <= '1';
+ addsub_cy_o <= '0';
+ opa_o <= acc_i;
+ opb_o <= ram_data_i;
+ when ADD_ACC_ROM =>
+ dcml_data_o <= ( others => '0' );
+ mltplcnd_o <= ( others => '0' );
+ mltplctr_o <= ( others => '0' );
+ dvdnd_o <= ( others => '0' );
+ dvsor_o <= ( others => '0' );
+ addsub_o <= '1';
+ addsub_cy_o <= '0';
+ opa_o <= acc_i;
+ opb_o <= rom_data_i;
+ when ADDC_ACC_RAM =>
+ dcml_data_o <= ( others => '0' );
+ mltplcnd_o <= ( others => '0' );
+ mltplctr_o <= ( others => '0' );
+ dvdnd_o <= ( others => '0' );
+ dvsor_o <= ( others => '0' );
+ addsub_o <= '1';
+ addsub_cy_o <= cy_i((DWIDTH-1)/4);
+ opa_o <= acc_i;
+ opb_o <= ram_data_i;
+ when ADDC_ACC_ROM =>
+ dcml_data_o <= ( others => '0' );
+ mltplcnd_o <= ( others => '0' );
+ mltplctr_o <= ( others => '0' );
+ dvdnd_o <= ( others => '0' );
+ dvsor_o <= ( others => '0' );
+ addsub_o <= '1';
+ addsub_cy_o <= cy_i((DWIDTH-1)/4);
+ opa_o <= acc_i;
+ opb_o <= rom_data_i;
+ when others =>
+ dcml_data_o <= ( others => '0' );
+ mltplcnd_o <= ( others => '0' );
+ mltplctr_o <= ( others => '0' );
+ dvdnd_o <= ( others => '0' );
+ dvsor_o <= ( others => '0' );
+ addsub_o <= '0';
+ addsub_cy_o <= '0';
+ opa_o <= ( others => '0' );
+ opb_o <= ( others => '0' );
+ end case;
+ end process p_ext_mux;
+
+ -- Multiplex the results for all the units contributing to the ALU.
+ p_rslt_mux : process (ram_data_i,
+ cy_i,
+ ov_i,
+ product_i,
+ qutnt_i,
+ rmndr_i,
+ result_i,
+ new_cy_i,
+ addsub_rslt_i,
+ addsub_cy_i,
+ addsub_ov_i,
+ dcml_data_i,
+ dcml_cy_i,
+ cmd_i)
+ begin
+ case cmd_i is
+ when DA =>
+ if (C_IMPL_DA /= 0) then
+ result_a_o <= dcml_data_i;
+ result_b_o <= ( others => '0' );
+ cy_o <= cy_i;
+ cy_o((DWIDTH-1)/4) <= dcml_cy_i;
+ ov_o <= ov_i;
+ else
+ result_a_o <= ( others => '0' );
+ result_b_o <= ( others => '0' );
+ cy_o <= conv_std_logic_vector(0,(DWIDTH-1)/4+1);
+ ov_o <= '0';
+ end if;
+ when DIV_ACC_RAM =>
+ if (C_IMPL_DIV /= 0) then
+ result_a_o <= qutnt_i;
+ result_b_o <= rmndr_i;
+ cy_o <= conv_std_logic_vector(0,(DWIDTH-1)/4+1);
+ if ram_data_i = conv_std_logic_vector(0,DWIDTH) then
+ ov_o <= '1';
+ else
+ ov_o <= '0';
+ end if;
+ else
+ result_a_o <= ( others => '0' );
+ result_b_o <= ( others => '0' );
+ cy_o <= conv_std_logic_vector(0,(DWIDTH-1)/4+1);
+ ov_o <= '0';
+ end if;
+ when MUL_ACC_RAM =>
+ if (C_IMPL_MUL /= 0) then
+ result_a_o <= product_i(DWIDTH-1 downto 0);
+ result_b_o <= product_i(DWIDTH*2-1 downto DWIDTH);
+ cy_o <= conv_std_logic_vector(0,(DWIDTH-1)/4+1);
+ if product_i(DWIDTH*2-1 downto DWIDTH)
+ = conv_std_logic_vector(0, DWIDTH) then
+ ov_o <= '0';
+ else
+ ov_o <= '1';
+ end if;
+ else
+ result_a_o <= ( others => '0' );
+ result_b_o <= ( others => '0' );
+ cy_o <= conv_std_logic_vector(0,(DWIDTH-1)/4+1);
+ ov_o <= '0';
+ end if;
+ when SUB_ACC_RAM | SUB_ACC_ROM | ADD_ACC_RAM | ADD_ACC_ROM |
+ ADDC_ACC_RAM | ADDC_ACC_ROM =>
+ result_a_o <= addsub_rslt_i;
+ result_b_o <= ( others => '0' );
+ cy_o <= addsub_cy_i;
+ ov_o <= addsub_ov_i;
+ when INC_ACC | INC_RAM | DEC_ACC | DEC_RAM =>
+ result_a_o <= addsub_rslt_i;
+ result_b_o <= ( others => '0' );
+ cy_o <= cy_i;
+ ov_o <= addsub_ov_i;
+ when others =>
+ result_a_o <= result_i;
+ result_b_o <= ( others => '0' );
+ cy_o <= new_cy_i;
+ ov_o <= ov_i;
+ end case;
+ end process p_rslt_mux;
+
+end rtl;
diff --git a/testsuite/synth/issue2273/alumux_rtl_cfg.vhd b/testsuite/synth/issue2273/alumux_rtl_cfg.vhd
new file mode 100644
index 000000000..a09557bb4
--- /dev/null
+++ b/testsuite/synth/issue2273/alumux_rtl_cfg.vhd
@@ -0,0 +1,68 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: alumux_rtl_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Select data path according to the actual command.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration alumux_rtl_cfg of alumux is
+ for rtl
+ end for;
+end alumux_rtl_cfg;
diff --git a/testsuite/synth/issue2273/comb_divider_.vhd b/testsuite/synth/issue2273/comb_divider_.vhd
new file mode 100644
index 000000000..1161c81e0
--- /dev/null
+++ b/testsuite/synth/issue2273/comb_divider_.vhd
@@ -0,0 +1,82 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: comb_divider_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Divider with parameteriseable data width. Realised
+-- using combinational logic only.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+-----------------------------ENTITY DECLARATION--------------------------------
+
+entity comb_divider is
+
+ generic (DWIDTH : integer := 8);
+
+ port (dvdnd_i : in std_logic_vector(DWIDTH-1 downto 0); -- Dividend
+ dvsor_i : in std_logic_vector(DWIDTH-1 downto 0); -- Divisor
+ qutnt_o : out std_logic_vector(DWIDTH-1 downto 0); -- Quotient
+ rmndr_o : out std_logic_vector(DWIDTH-1 downto 0)); -- Remainder
+
+end comb_divider;
+
diff --git a/testsuite/synth/issue2273/comb_divider_rtl.vhd b/testsuite/synth/issue2273/comb_divider_rtl.vhd
new file mode 100644
index 000000000..6ca5044a6
--- /dev/null
+++ b/testsuite/synth/issue2273/comb_divider_rtl.vhd
@@ -0,0 +1,114 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: comb_divider_rtl.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Divider with parameteriseable data width. Realised
+-- using combinational logic only.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture rtl of comb_divider is
+
+begin -- rtl
+
+ -- purpose: Divide dvdnd_i through dvsor_i and deliver the result to qutnt_o
+ -- and the remainder to rmndr_o.
+ -- type : combinational
+ -- inputs : dvdnd_i, dvsor_i
+ -- outputs: qutnt_o, rmndr_o
+ p_divide: process (dvdnd_i, dvsor_i)
+
+ variable v_actl_dvdnd : unsigned(DWIDTH-1 downto 0);
+ variable v_dffrnc : unsigned(DWIDTH-1 downto 0);
+ variable v_qutnt : unsigned(DWIDTH-1 downto 0);
+
+ begin -- process p_divide
+
+ v_actl_dvdnd := unsigned(dvdnd_i);
+
+ for i in DWIDTH-1 downto 0 loop
+ -- If the divisor can be subtracted from this part of the dividend, then
+ -- the corresponding bit of the quotient has to be 1, otherwise 0.
+ if conv_std_logic_vector(v_actl_dvdnd(DWIDTH-1 downto i),DWIDTH) >=
+ dvsor_i then
+ -- Divisor can be subtracted
+ v_qutnt(i) := '1';
+ v_dffrnc := conv_unsigned(v_actl_dvdnd(DWIDTH-1 downto i),DWIDTH)
+ - unsigned(dvsor_i);
+ -- As long as this is not the last step of calculation, shift the
+ -- intermediate result.
+ if i /= 0 then
+ v_actl_dvdnd(DWIDTH-1 downto i) := v_dffrnc(DWIDTH-1-i downto 0);
+ v_actl_dvdnd(i-1) := dvdnd_i(i-1);
+ end if;
+ else
+ -- Divisor is greater than this part of the dividend.
+ v_qutnt(i) := '0';
+ v_dffrnc := conv_unsigned(v_actl_dvdnd(DWIDTH-1 downto i),DWIDTH);
+ end if;
+ end loop; -- i
+
+ rmndr_o <= std_logic_vector(v_dffrnc);
+ qutnt_o <= std_logic_vector(v_qutnt);
+
+ end process p_divide;
+
+end rtl;
+
+
diff --git a/testsuite/synth/issue2273/comb_divider_rtl_cfg.vhd b/testsuite/synth/issue2273/comb_divider_rtl_cfg.vhd
new file mode 100644
index 000000000..ddec90a11
--- /dev/null
+++ b/testsuite/synth/issue2273/comb_divider_rtl_cfg.vhd
@@ -0,0 +1,72 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: comb_divider_rtl_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Divider with parameteriseable data width. Realised
+-- using combinational logic only.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration comb_divider_rtl_cfg of comb_divider is
+
+ for rtl
+
+ end for;
+
+end comb_divider_rtl_cfg;
diff --git a/testsuite/synth/issue2273/comb_mltplr_.vhd b/testsuite/synth/issue2273/comb_mltplr_.vhd
new file mode 100644
index 000000000..d0c620c45
--- /dev/null
+++ b/testsuite/synth/issue2273/comb_mltplr_.vhd
@@ -0,0 +1,81 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: comb_mltplr_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Multiplier with parameteriseable data width. Realised
+-- using combinational logic only.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+-----------------------------ENTITY DECLARATION--------------------------------
+
+entity comb_mltplr is
+
+ generic (DWIDTH : integer := 8);
+
+ port (mltplcnd_i : in std_logic_vector(DWIDTH-1 downto 0); -- Multiplicand
+ mltplctr_i : in std_logic_vector(DWIDTH-1 downto 0); -- Multiplicator
+ product_o : out std_logic_vector((DWIDTH*2)-1 downto 0)); -- Product
+
+end comb_mltplr;
+
diff --git a/testsuite/synth/issue2273/comb_mltplr_rtl.vhd b/testsuite/synth/issue2273/comb_mltplr_rtl.vhd
new file mode 100644
index 000000000..8e7e52677
--- /dev/null
+++ b/testsuite/synth/issue2273/comb_mltplr_rtl.vhd
@@ -0,0 +1,88 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: comb_mltplr_rtl.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Multiplier with parameteriseable data width. Realised
+-- using combinational logic only.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture rtl of comb_mltplr is
+
+begin -- rtl
+
+ -- purpose: Multiply the multiplicand with the multiplicator.
+ -- type : combinational
+ -- inputs : dvdnd_i, dvsor_i
+ -- outputs: product_o
+ p_mltply: process (mltplctr_i, mltplcnd_i)
+
+ variable v_product : unsigned(DWIDTH*2-1 downto 0);
+
+ begin -- process p_divide
+
+ v_product := conv_unsigned(unsigned(mltplctr_i)
+ * unsigned(mltplcnd_i),DWIDTH*2);
+ product_o <= std_logic_vector(v_product);
+
+ end process p_mltply;
+
+end rtl;
+
+
diff --git a/testsuite/synth/issue2273/comb_mltplr_rtl_cfg.vhd b/testsuite/synth/issue2273/comb_mltplr_rtl_cfg.vhd
new file mode 100644
index 000000000..3878fc28c
--- /dev/null
+++ b/testsuite/synth/issue2273/comb_mltplr_rtl_cfg.vhd
@@ -0,0 +1,72 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: comb_mltplr_rtl_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Multiplier with parameteriseable data width. Realised
+-- using combinational logic only.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration comb_mltplr_rtl_cfg of comb_mltplr is
+
+ for rtl
+
+ end for;
+
+end comb_mltplr_rtl_cfg;
diff --git a/testsuite/synth/issue2273/control_fsm_.vhd b/testsuite/synth/issue2273/control_fsm_.vhd
new file mode 100644
index 000000000..5afac977b
--- /dev/null
+++ b/testsuite/synth/issue2273/control_fsm_.vhd
@@ -0,0 +1,124 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Helmut Mayrhofer
+--
+-- Filename: control_fsm_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.6 $
+--
+-- Date of Latest Version: $Date: 2006-09-07 09:57:24 $
+--
+--
+-- Description: Decode instruction and execute it. Pure combinational
+-- descripton of the finite state machine.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+library work;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+use work.mc8051_p.all;
+
+
+------------------------ ENTITY DECLARATION -------------------------
+entity control_fsm is
+
+ port (state_i : in t_state; -- actual state
+ help_i : in std_logic_vector (7 downto 0); -- general help-reg
+ bit_data_i : in std_logic; -- bitdata from regs
+ aludata_i : in std_logic_vector (7 downto 0); -- ALU result
+ command_i : in std_logic_vector (7 downto 0); -- actual command
+ inthigh_i : in std_logic; -- high priority int is running
+ intlow_i : in std_logic; -- low priority int is running
+ intpre_i : in std_logic; -- an interrupt must start
+ intpre2_i : in std_logic; -- prepare for interrupt
+ intblock_i : in std_logic; -- interrupt delay at RETI, IE, IP
+ ti_i : in std_logic;
+ ri_i : in std_logic;
+ ie0_i : in std_logic;
+ ie1_i : in std_logic;
+ tf0_i : in std_logic;
+ tf1_i : in std_logic;
+ acc : in std_logic_vector(7 downto 0);
+ psw : in std_logic_vector(7 downto 0);
+ ie : in std_logic_vector(7 downto 0);
+ ip : in std_logic_vector(7 downto 0);
+
+ alu_cmd_o : out std_logic_vector (5 downto 0); -- ALU code
+ pc_inc_en_o : out std_logic_vector (3 downto 0);
+ nextstate_o : out t_state; -- enable signal for state
+ adr_mux_o : out std_logic_vector (3 downto 0);
+ adrx_mux_o : out std_logic_vector (1 downto 0);
+ wrx_mux_o : out std_logic;
+ data_mux_o : out std_logic_vector (3 downto 0);
+ bdata_mux_o : out std_logic_vector (3 downto 0);
+ regs_wr_en_o : out std_logic_vector (2 downto 0);
+ help_en_o : out std_logic_vector (3 downto 0);
+ help16_en_o : out std_logic_vector (1 downto 0);
+ helpb_en_o : out std_logic;
+ inthigh_en_o : out std_logic;
+ intlow_en_o : out std_logic;
+ intpre2_en_o : out std_logic;
+ inthigh_d_o : out std_logic;
+ intlow_d_o : out std_logic;
+ intpre2_d_o : out std_logic;
+ ext0isr_d_o : out std_logic;
+ ext1isr_d_o : out std_logic;
+ ext0isrh_d_o : out std_logic;
+ ext1isrh_d_o : out std_logic;
+ ext0isr_en_o : out std_logic;
+ ext1isr_en_o : out std_logic;
+ ext0isrh_en_o : out std_logic;
+ ext1isrh_en_o : out std_logic);
+
+end control_fsm;
diff --git a/testsuite/synth/issue2273/control_fsm_rtl.vhd b/testsuite/synth/issue2273/control_fsm_rtl.vhd
new file mode 100644
index 000000000..698d30bb1
--- /dev/null
+++ b/testsuite/synth/issue2273/control_fsm_rtl.vhd
@@ -0,0 +1,2171 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Helmut Mayrhofer
+--
+-- Filename: control_fsm_rtl.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.10 $
+--
+-- Date of Latest Version: $Date: 2010-03-24 10:20:48 $
+--
+--
+-- Description: Decode instruction and execute it. Pure combinational
+-- descripton of the finite state machine.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture rtl of control_fsm is
+
+ alias CY : std_logic is psw(7); -- carry
+ alias AC : std_logic is psw(6); -- auxilary carry
+ alias OV : std_logic is psw(2); -- overflow flag
+ alias EA: std_logic is ie(7); -- enable interupts
+ alias ES: std_logic is ie(4); -- enable serial interupt
+ alias ET1: std_logic is ie(3); -- enable timer 1 interupt
+ alias EX1: std_logic is ie(2); -- enable external 1 interupt
+ alias ET0: std_logic is ie(1); -- enable timer 0 interupt
+ alias EX0: std_logic is ie(0); -- enable external 0 interupt
+ alias PS0: std_logic is ip(4); -- priority of serial interupt
+ alias PT1: std_logic is ip(3); -- priority of timer1 interupt
+ alias PX1: std_logic is ip(2); -- priority of ext1 interupt
+ alias PT0: std_logic is ip(1); -- priority of timer0 interupt
+ alias PX0: std_logic is ip(0); -- priority of ext0 interupt
+
+ signal state: t_state; -- actual state
+ signal s_nextstate: t_state; -- enable signal for state
+ signal s_instr_category : t_instr_category; -- predecoded insturction
+
+ signal s_help: unsigned (7 downto 0); -- general help-register
+
+ signal s_bit_data : std_logic; -- bitdata from MUX
+ signal s_intpre: std_logic; -- an interrupt must start
+ signal s_intpre2: std_logic; -- prepare for interrupt
+ signal s_inthigh: std_logic; -- high priority int is running
+ signal s_intlow: std_logic; -- low priority int is running
+
+ signal s_tf1 : std_logic; -- Timer1-Overflowflag
+ signal s_tf0 : std_logic; -- Timer0-Overflowflag
+ signal s_ie1 : std_logic; -- ExtINT1-Flag
+ signal s_ie0 : std_logic; -- ExtINT0-Flag
+
+ signal s_ri : std_logic; -- serial receive-ready
+ signal s_ti : std_logic; -- serial transmit-ready
+
+ signal s_command: std_logic_vector (7 downto 0); -- actual command
+
+ signal s_pc_inc_en : std_logic_vector (3 downto 0); -- pc control
+ signal s_regs_wr_en : std_logic_vector (2 downto 0); -- write control
+ signal s_data_mux : std_logic_vector (3 downto 0); -- data control
+ signal s_bdata_mux : std_logic_vector (3 downto 0); -- bitdata control
+ signal s_adr_mux : std_logic_vector (3 downto 0); -- adress control
+ signal s_adrx_mux : std_logic_vector (1 downto 0); -- ext. adress control
+ signal s_wrx_mux : std_logic; -- ext. write control
+ signal s_help_en : std_logic_vector (3 downto 0); -- helpreg control
+ signal s_help16_en : std_logic_vector (1 downto 0); -- help16 control
+ signal s_helpb_en : std_logic; -- helpbit control
+ signal s_intpre2_d : std_logic; -- intput of intpre2
+ signal s_intpre2_en : std_logic; -- control
+ signal s_intlow_d : std_logic; -- input of intlow
+ signal s_intlow_en : std_logic; -- control
+ signal s_inthigh_d : std_logic; -- input of inthigh
+ signal s_inthigh_en : std_logic; -- control
+ signal s_ext0isr_d : std_logic; -- ext int 0 ISR running if set
+ signal s_ext1isr_d : std_logic; -- ext int 1 ISR running if set
+ signal s_ext0isrh_d : std_logic; -- ext int 0 ISR has high priority if 1
+ signal s_ext1isrh_d : std_logic; -- ext int 1 ISR has high priority if 1
+ signal s_ext0isr_en : std_logic;
+ signal s_ext1isr_en : std_logic;
+ signal s_ext0isrh_en : std_logic;
+ signal s_ext1isrh_en : std_logic;
+
+begin
+
+ -- some simple signal-assignments for outputs
+
+ pc_inc_en_o <= s_pc_inc_en;
+ nextstate_o <= s_nextstate;
+ adr_mux_o <= s_adr_mux;
+ adrx_mux_o <= s_adrx_mux;
+ wrx_mux_o <= s_wrx_mux;
+ data_mux_o <= s_data_mux;
+ bdata_mux_o <= s_bdata_mux;
+ regs_wr_en_o <= s_regs_wr_en;
+ help_en_o <= s_help_en;
+ help16_en_o <= s_help16_en;
+ helpb_en_o <= s_helpb_en;
+ inthigh_en_o <= s_inthigh_en;
+ intlow_en_o <= s_intlow_en;
+ intpre2_en_o <= s_intpre2_en;
+ inthigh_d_o <= s_inthigh_d;
+ intlow_d_o <= s_intlow_d;
+ intpre2_d_o <= s_intpre2_d;
+ ext0isr_d_o <= s_ext0isr_d;
+ ext1isr_d_o <= s_ext1isr_d;
+ ext0isrh_d_o <= s_ext0isrh_d;
+ ext1isrh_d_o <= s_ext1isrh_d;
+ ext0isr_en_o <= s_ext0isr_en;
+ ext1isr_en_o <= s_ext1isr_en;
+ ext0isrh_en_o <= s_ext0isrh_en;
+ ext1isrh_en_o <= s_ext1isrh_en;
+
+ -- some simple signal assignments from intputs
+
+ state <= state_i;
+ s_help <= unsigned(help_i);
+ s_bit_data <= bit_data_i;
+ s_command <= command_i;
+ s_inthigh <= inthigh_i;
+ s_intlow <= intlow_i;
+ s_intpre <= intpre_i;
+ s_intpre2 <= intpre2_i;
+ s_ti <= ti_i;
+ s_ri <= ri_i;
+ s_ie0 <= ie0_i;
+ s_ie1 <= ie1_i;
+ s_tf0 <= tf0_i;
+ s_tf1 <= tf1_i;
+
+ -- predecode instruction
+ s_instr_category <=
+ IC_ACALL when s_command(4 downto 0) = ACALL else
+ IC_ADD_A_RR when s_command(7 downto 3) = ADD_A_RR else
+ IC_ADD_A_D when s_command = ADD_A_D else
+ IC_ADD_A_ATRI when s_command(7 downto 1) = ADD_A_ATRI else
+ IC_ADD_A_DATA when s_command = ADD_A_DATA else
+ IC_ADDC_A_RR when s_command(7 downto 3) = ADDC_A_RR else
+ IC_ADDC_A_D when s_command = ADDC_A_D else
+ IC_ADDC_A_ATRI when s_command(7 downto 1) = ADDC_A_ATRI else
+ IC_ADDC_A_DATA when s_command = ADDC_A_DATA else
+ IC_AJMP when s_command(4 downto 0) = AJMP else
+ IC_ANL_A_RR when s_command(7 downto 3) = ANL_A_RR else
+ IC_ANL_A_D when s_command = ANL_A_D else
+ IC_ANL_A_ATRI when s_command(7 downto 1) = ANL_A_ATRI else
+ IC_ANL_A_DATA when s_command = ANL_A_DATA else
+ IC_ANL_D_A when s_command = ANL_D_A else
+ IC_ANL_D_DATA when s_command = ANL_D_DATA else
+ IC_ANL_C_BIT when s_command = ANL_C_BIT else
+ IC_ANL_C_NBIT when s_command = ANL_C_NBIT else
+ IC_CJNE_A_D when s_command = CJNE_A_D else
+ IC_CJNE_A_DATA when s_command = CJNE_A_DATA else
+ IC_CJNE_RR_DATA when s_command(7 downto 3) = CJNE_RR_DATA else
+ IC_CJNE_ATRI_DATA when s_command(7 downto 1) = CJNE_ATRI_DATA else
+ IC_CLR_A when s_command = CLR_A else
+ IC_CLR_C when s_command = CLR_C else
+ IC_CLR_BIT when s_command = CLR_BIT else
+ IC_CPL_A when s_command = CPL_A else
+ IC_CPL_C when s_command = CPL_C else
+ IC_CPL_BIT when s_command = CPL_BIT else
+ IC_DA_A when s_command = DA_A else
+ IC_DEC_A when s_command = DEC_A else
+ IC_DEC_RR when s_command(7 downto 3) = DEC_RR else
+ IC_DEC_D when s_command = DEC_D else
+ IC_DEC_ATRI when s_command(7 downto 1) = DEC_ATRI else
+ IC_DIV_AB when s_command = DIV_AB else
+ IC_DJNZ_RR when s_command(7 downto 3) = DJNZ_RR else
+ IC_DJNZ_D when s_command = DJNZ_D else
+ IC_INC_A when s_command = INC_A else
+ IC_INC_RR when s_command(7 downto 3) = INC_RR else
+ IC_INC_D when s_command = INC_D else
+ IC_INC_ATRI when s_command(7 downto 1) = INC_ATRI else
+ IC_INC_DPTR when s_command = INC_DPTR else
+ IC_JB when s_command = JB else
+ IC_JBC when s_command = JBC else
+ IC_JC when s_command = JC else
+ IC_JMP_A_DPTR when s_command = JMP_A_DPTR else
+ IC_JNB when s_command = JNB else
+ IC_JNC when s_command = JNC else
+ IC_JNZ when s_command = JNZ else
+ IC_JZ when s_command = JZ else
+ IC_LCALL when s_command = LCALL else
+ IC_LJMP when s_command = LJMP else
+ IC_MOV_A_RR when s_command(7 downto 3) = MOV_A_RR else
+ IC_MOV_A_D when s_command = MOV_A_D else
+ IC_MOV_A_ATRI when s_command(7 downto 1) = MOV_A_ATRI else
+ IC_MOV_A_DATA when s_command = MOV_A_DATA else
+ IC_MOV_RR_A when s_command(7 downto 3) = MOV_RR_A else
+ IC_MOV_RR_D when s_command(7 downto 3) = MOV_RR_D else
+ IC_MOV_RR_DATA when s_command(7 downto 3) = MOV_RR_DATA else
+ IC_MOV_D_A when s_command = MOV_D_A else
+ IC_MOV_D_RR when s_command(7 downto 3) = MOV_D_RR else
+ IC_MOV_D_D when s_command = MOV_D_D else
+ IC_MOV_D_ATRI when s_command(7 downto 1) = MOV_D_ATRI else
+ IC_MOV_D_DATA when s_command = MOV_D_DATA else
+ IC_MOV_ATRI_A when s_command(7 downto 1) = MOV_ATRI_A else
+ IC_MOV_ATRI_D when s_command(7 downto 1) = MOV_ATRI_D else
+ IC_MOV_ATRI_DATA when s_command(7 downto 1) = MOV_ATRI_DATA else
+ IC_MOVC_A_ATDPTR when s_command = MOVC_A_ATDPTR else
+ IC_MOVC_A_ATPC when s_command = MOVC_A_ATPC else
+ IC_MOVX_A_ATRI when s_command(7 downto 1) = MOVX_A_ATRI else
+ IC_MOVX_A_ATDPTR when s_command = MOVX_A_ATDPTR else
+ IC_MOVX_ATRI_A when s_command(7 downto 1) = MOVX_ATRI_A else
+ IC_MOVX_ATDPTR_A when s_command = MOVX_ATDPTR_A else
+ IC_MOV_C_BIT when s_command = MOV_C_BIT else
+ IC_MOV_BIT_C when s_command = MOV_BIT_C else
+ IC_MOV_DPTR_DATA when s_command = MOV_DPTR_DATA else
+ IC_MUL_AB when s_command = MUL_AB else
+ IC_NOP when s_command = NOP else
+ IC_ORL_A_RR when s_command(7 downto 3) = ORL_A_RR else
+ IC_ORL_A_D when s_command = ORL_A_D else
+ IC_ORL_A_ATRI when s_command(7 downto 1) = ORL_A_ATRI else
+ IC_ORL_A_DATA when s_command = ORL_A_DATA else
+ IC_ORL_D_A when s_command = ORL_D_A else
+ IC_ORL_D_DATA when s_command = ORL_D_DATA else
+ IC_ORL_C_BIT when s_command = ORL_C_BIT else
+ IC_ORL_C_NBIT when s_command = ORL_C_NBIT else
+ IC_POP when s_command = POP else
+ IC_PUSH when s_command = PUSH else
+ IC_RET when s_command = RET else
+ IC_RETI when s_command = RETI else
+ IC_RL_A when s_command = RL_A else
+ IC_RLC_A when s_command = RLC_A else
+ IC_RR_A when s_command = RR_A else
+ IC_RRC_A when s_command = RRC_A else
+ IC_SETB_C when s_command = SETB_C else
+ IC_SETB_BIT when s_command = SETB_BIT else
+ IC_SJMP when s_command = SJMP else
+ IC_SUBB_A_RR when s_command(7 downto 3) = SUBB_A_RR else
+ IC_SUBB_A_D when s_command = SUBB_A_D else
+ IC_SUBB_A_ATRI when s_command(7 downto 1) = SUBB_A_ATRI else
+ IC_SUBB_A_DATA when s_command = SUBB_A_DATA else
+ IC_SWAP_A when s_command = SWAP_A else
+ IC_XCH_A_RR when s_command(7 downto 3) = XCH_A_RR else
+ IC_XCH_A_D when s_command = XCH_A_D else
+ IC_XCH_A_ATRI when s_command(7 downto 1) = XCH_A_ATRI else
+ IC_XCHD_A_ATRI when s_command(7 downto 1) = XCHD_A_ATRI else
+ IC_XRL_A_RR when s_command(7 downto 3) = XRL_A_RR else
+ IC_XRL_A_D when s_command = XRL_A_D else
+ IC_XRL_A_ATRI when s_command(7 downto 1) = XRL_A_ATRI else
+ IC_XRL_A_DATA when s_command = XRL_A_DATA else
+ IC_XRL_D_A when s_command = XRL_D_A else
+ IC_XRL_D_DATA when s_command = XRL_D_DATA else
+ IC_NOP;
+
+------------------------------------------------------------------------------
+-- purpose: main-process to control the mcu
+-- includes the interupt-handling and the state machine
+-- inputs: state,s_help,s_ti,s_ri,s_ie0,s_ie1,s_tf0,s_tf1,
+-- s_bit_data,aludata_i,s_command,s_inthigh,
+-- s_intlow,acc,psw,s_intpre,s_intpre2,ie,ip
+-- outputs: pc_inc_en_o,s_nextstate_o,adr_mux_o,data_mux_o,bdata_mux_o
+-- regs_wr_en_o,help_en_o,help16_en_o,helpb_en_o,inthigh_en_o
+-- intlow_en_o,intpre2_en_o,inthigh_d_o,intlow_d_o,intpre2_d_o
+------------------------------------------------------------------------------
+
+ p_state: process (state,s_help,s_ti,s_ri,s_ie0,s_ie1,s_tf0,s_tf1,
+ s_bit_data,aludata_i,s_instr_category,s_inthigh,
+ s_intlow,acc,psw,s_intpre,s_intpre2,ie,ip,intblock_i)
+ begin
+ s_data_mux <= "0000"; -- default values
+ s_adr_mux <= "0000";
+ s_bdata_mux <= "0000";
+ alu_cmd_o <= OFF;
+ s_regs_wr_en <= "000";
+ s_help_en <= "0000";
+ s_help16_en <= "00";
+ s_helpb_en <= '0';
+ s_pc_inc_en <= "0000";
+ s_inthigh_en <= '0';
+ s_intlow_en <= '0';
+ s_intpre2_en <= '0';
+ s_inthigh_d <= '0';
+ s_intlow_d <= '0';
+ s_intpre2_d <= '0';
+ s_adrx_mux <= "00";
+ s_wrx_mux <= '0';
+ s_nextstate <= FETCH;
+ s_ext0isr_d <= '0';
+ s_ext1isr_d <= '0';
+ s_ext0isrh_d <= '0';
+ s_ext1isrh_d <= '0';
+ s_ext0isr_en <= '0';
+ s_ext1isr_en <= '0';
+ s_ext0isrh_en <= '0';
+ s_ext1isrh_en <= '0';
+
+ if state=STARTUP then
+ -- Power up wait cycle
+ NULL;
+ else
+ -- begin of starting the interrupt procedure
+ -- saving the old adress
+ if intblock_i = '0' and s_instr_category /= IC_RETI and -- fixes bug when
+ -- a higher priority interrupt occurred during the RETI of a lower priority one
+ -- by wickerwaka https://github.com/MiSTer-devel/Arcade-IremM72_MiSTer/commit/2218dc0
+ ((s_intpre='1' and state=FETCH) or s_intpre2='1') then
+ if state=FETCH then
+ s_intpre2_en <= '1';
+ s_intpre2_d <= '1';
+ s_regs_wr_en <= "001"; -- increment stackpointer
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ if (PX0 and EX0 and s_ie0)='1' then -- external interrupt 0
+ s_help_en <= "0101"; -- interruptvector 0003h
+ s_inthigh_d <= '1';
+ s_inthigh_en <= '1';
+ s_adr_mux <= "0001";
+ s_regs_wr_en <= "110"; -- reset IE0
+ s_ext0isrh_d <= '1';
+ s_ext0isrh_en <= '1';
+ elsif (PT0 and ET0 and s_tf0)='1' then -- timer interrupt 0
+ s_help_en <= "0110"; -- interruptvector 000Bh
+ s_inthigh_d <= '1';
+ s_inthigh_en <= '1';
+ s_adr_mux <= "0010";
+ s_regs_wr_en <= "110"; -- reset TF0
+ elsif (PX1 and EX1 and s_ie1)='1' then -- external interrupt 1
+ s_help_en <= "0111"; -- interruptvector 0013h
+ s_inthigh_d <= '1';
+ s_inthigh_en <= '1';
+ s_adr_mux <= "0011";
+ s_regs_wr_en <= "110"; -- reset IE1
+ s_ext1isrh_d <= '1';
+ s_ext1isrh_en <= '1';
+ elsif (PT1 and ET1 and s_tf1)='1' then -- timer interrupt 1
+ s_help_en <= "1000"; -- interruptvector 001Bh
+ s_inthigh_d <= '1';
+ s_inthigh_en <= '1';
+ s_adr_mux <= "0100";
+ s_regs_wr_en <= "110"; -- reset TF1
+ elsif (PS0 and ES and (s_ri or s_ti))='1' then -- serial interrupt 0
+ s_help_en <= "1001"; -- interruptvector 0023h
+ s_inthigh_d <= '1';
+ s_inthigh_en <= '1';
+ elsif (EX0 and s_ie0)='1' then -- external interrupt 0 low priority
+ s_help_en <= "0101"; -- interruptvector 0003h
+ s_intlow_d <= '1';
+ s_intlow_en <= '1';
+ s_adr_mux <= "0001";
+ s_regs_wr_en <= "110"; -- reset IE0
+ s_ext0isr_d <= '1';
+ s_ext0isr_en <= '1';
+ elsif (ET0 and s_tf0)='1' then -- timer interrupt 0 low priority
+ s_help_en <= "0110"; -- interruptvector 000Bh
+ s_intlow_d <= '1';
+ s_intlow_en <= '1';
+ s_adr_mux <= "0010";
+ s_regs_wr_en <= "110"; -- reset TF0
+ elsif (EX1 and s_ie1)='1' then -- external interrupt 1 low priority
+ s_help_en <= "0111"; -- interruptvector 0013h
+ s_intlow_d <= '1';
+ s_intlow_en <= '1';
+ s_adr_mux <= "0011";
+ s_regs_wr_en <= "110"; -- reset IE1
+ s_ext1isr_d <= '1';
+ s_ext1isr_en <= '1';
+ elsif (ET1 and s_tf1)='1' then -- timer interrupt 1 low priority
+ s_help_en <= "1000"; -- interruptvector 001Bh
+ s_intlow_d <= '1';
+ s_intlow_en <= '1';
+ s_adr_mux <= "0100";
+ s_regs_wr_en <= "110"; -- reset TF1
+ elsif (ES and (s_ri or s_ti))='1' then -- serial int 0 low priority
+ s_help_en <= "1001"; -- interruptvector 0023h
+ s_intlow_d <= '1';
+ s_intlow_en <= '1';
+ else
+ NULL;
+ end if;
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "0101";
+ s_data_mux <= "0001"; -- data = pc(7 downto 0)
+ s_regs_wr_en <= "101"; -- write one byte and increment SP
+ s_nextstate <= EXEC3;
+ elsif state=EXEC3 then
+ s_intpre2_d <= '0';
+ s_intpre2_en <= '1';
+ s_adr_mux <= "0101";
+ s_data_mux <= "0010"; -- data = pc(15 downto 8)
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0011"; -- load program counter
+ s_nextstate <= FETCH;
+ else
+ s_nextstate <= FETCH;
+ end if;
+
+ -- end of starting interrupt procedure
+
+ else
+
+ case s_instr_category is
+
+ ---------------------------------------------------------------------
+
+ when IC_ACALL => -- ACALL addr11
+ if state=FETCH then
+ s_adr_mux <= "1111"; -- adress = sp + 1
+ s_data_mux <= "1110"; -- data = (pc+2)(7 downto 0)
+ s_regs_wr_en <= "101"; -- write one byte and increment SP
+ s_help16_en <= "10"; -- s_help16 = pc+2
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1111"; -- adress = sp + 1
+ s_data_mux <= "1101"; -- data = s_help16(15 downto 8)
+ s_regs_wr_en <= "101"; -- write one byte and increment SP
+ s_pc_inc_en <= "0100"; -- load PC with 11 bits (2k block)
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ADD_A_RR => -- ADD A,Rr
+ if state=FETCH then
+ s_adr_mux <= "0110"; -- adress = RR-adress
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= ADD_ACC_RAM; -- addition command (ACC + RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ADD_A_D => -- ADD A, direct
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- adress = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ alu_cmd_o <= ADD_ACC_RAM; -- addition command (ACC + RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ADD_A_ATRI => -- ADD A,@Ri
+ if state=FETCH then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= ADD_ACC_RAM; -- addition command (ACC + RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ADD_A_DATA => -- ADD A, DATA
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= ADD_ACC_ROM; -- addition command (ACC + ROM_DATA_I)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ADDC_A_RR => -- ADDC A,Rr
+ if state=FETCH then
+ s_adr_mux <= "0110"; -- adress = RR-adress
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= ADDC_ACC_RAM; -- addition command (ACC+RAM_DATA+CY)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ADDC_A_D => -- ADDC A, direct
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- adress = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ alu_cmd_o <= ADDC_ACC_RAM; -- addition command (ACC+RAM_DATA+CY)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ADDC_A_ATRI => -- ADDC A,@Ri
+ if state=FETCH then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= ADDC_ACC_RAM; -- addition command (ACC+RAM_DATA+CY)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ADDC_A_DATA => -- ADDC A, data
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= ADDC_ACC_ROM;-- addition command (ACC+ROM_DATA_I+CY)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_AJMP => -- AJMP addr11
+ if state=FETCH then
+ s_help16_en <= "10"; -- s_help16 = pc+2
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_pc_inc_en <= "0100"; -- load PC with 11 bits (2k block)
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ANL_A_RR => -- ANL A,Rr
+ if state=FETCH then
+ s_adr_mux <= "0110"; -- adress = RR-adress
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= AND_ACC_RAM; -- AND command (ACC ^ RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ANL_A_D => -- ANL A, direct
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ alu_cmd_o <= AND_ACC_RAM; -- AND command (ACC ^ RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ANL_A_ATRI => -- ANL A,ATRi
+ if state=FETCH then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= AND_ACC_RAM; -- AND command (ACC ^ RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+ when IC_ANL_A_DATA => -- ANL A, data
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= AND_ACC_ROM; -- AND command (ACC ^ ROM_DATA_I)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ANL_D_A => -- ANL direct, A
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- adress = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ alu_cmd_o <= AND_ACC_RAM; -- AND command (ACC ^ RAM_DATA)
+ s_adr_mux <= "1000"; -- adress = rom_data_i
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ANL_D_DATA => -- ANL direct, DATA
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_help_en <= "0001"; -- help = rom_data_i
+ s_adr_mux <= "1000"; -- adress = rom_data_i
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ alu_cmd_o <= AND_RAM_ROM; -- AND command (ROM_DATA_I ^ RAM_DATA)
+ s_adr_mux <= "1010"; -- adress = help
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ANL_C_BIT => -- ANL C, bit
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- adress = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_bdata_mux <= "0001"; -- bdata = s_bit_data and cy
+ s_regs_wr_en <= "110"; -- write one bit (automatic CY-address)
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ANL_C_NBIT => -- ANL C, /bit
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- adress = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_bdata_mux <= "0010"; -- bdata = not (s_bit_data and cy)
+ s_regs_wr_en <= "110"; -- write one bit (automatic CY-address)
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_CJNE_A_D => -- CJNE A, direct, rel
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ alu_cmd_o <= COMP_RAM_ACC; -- Compare RAM_DATA/ACC operation
+ if unsigned(aludata_i) /= 0 then
+ s_adr_mux <= "1011"; -- adress of CY
+ s_bdata_mux <= "0011"; -- bdata = cby_i
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0010"; -- add relativ adress to PC
+ else
+ s_adr_mux <= "1011"; -- adress of CY (CV: changed V1.5 according to specification: clear carry)
+ s_bdata_mux <= "0000"; -- bdata = 0
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ end if;
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_CJNE_A_DATA => -- CJNE A, #data, rel
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= COMP_ROM_ACC; -- Compare ROM_DATA_I/ACC operation
+ s_help_en <= "0010";
+ s_helpb_en <= '1'; -- save new_cy_i
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ if s_help /= 0 then
+ s_adr_mux <= "1011"; -- adress of CY
+ s_bdata_mux <= "0100"; -- bdata = s_helpb
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0010"; -- add relativ adress to PC
+ else
+ s_adr_mux <= "1011"; -- adress of CY (CV: changed V1.5 according to specification: clear carry)
+ s_bdata_mux <= "0000"; -- bdata = 0
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ end if;
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_CJNE_RR_DATA => -- CJNE RR, #data, rel
+ if state=FETCH then
+ s_adr_mux <= "0110"; -- address = rr-address
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= COMP_ROM_RAM;-- Compare ROM_DATA_I/RAM_DATA operat.
+ s_help_en <= "0010"; -- save aludata_i
+ s_helpb_en <= '1'; -- save new_cy_i
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ if s_help /= 0 then
+ s_adr_mux <= "1011"; -- adress of CY
+ s_bdata_mux <= "0100"; -- bdata = s_helpb
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0010"; -- add relativ adress to PC
+ else
+ s_adr_mux <= "1011"; -- adress of CY (CV: changed V1.5 according to specification: clear carry)
+ s_bdata_mux <= "0000"; -- bdata = 0
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ end if;
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_CJNE_ATRI_DATA => -- CJNE @Ri, #data, rel
+ if state=FETCH then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= COMP_ROM_RAM; -- Compare ROM_/RAM_DATA operation
+ s_help_en <= "0010"; -- save aludata_i
+ s_helpb_en <= '1'; -- save new_cy_i
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ if s_help /= 0 then
+ s_adr_mux <= "1011"; -- adress of CY
+ s_bdata_mux <= "0100"; -- bdata = s_helpb
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0010"; -- add relativ adress to PC
+ else
+ s_adr_mux <= "1011"; -- adress of CY (CV: changed V1.5 according to specification: clear carry)
+ s_bdata_mux <= "0000"; -- bdata = 0
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ end if;
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_CLR_A => -- CLR A
+ s_data_mux <= "0000"; -- data = 0
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_CLR_C => -- CLR C
+ s_adr_mux <= "1011"; -- adress of CY
+ s_bdata_mux <= "0000"; -- bdata = 0
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_CLR_BIT => -- CLR bit
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_bdata_mux <= "0000"; -- bdata = 0
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_CPL_A => -- CPL A
+ alu_cmd_o <= INV_ACC; -- complement operation
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_CPL_C => -- CPL C
+ s_adr_mux <= "1011"; -- adress of CY
+ s_bdata_mux <= "0101"; -- bdata = not cy
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_CPL_BIT => -- CPL bit
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- bit adress
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "1000"; -- bit adress
+ s_bdata_mux <= "0110"; -- bdata = not s_bit_data
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ else
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_DA_A => -- DA A
+ alu_cmd_o <= DA; -- DA operation
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "111"; -- write ACC and CY (special operation)
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_DEC_A => -- DEC A
+ alu_cmd_o <= DEC_ACC; -- decrement operation
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_DEC_RR => -- DEC Rr
+ if state=FETCH then
+ s_adr_mux <= "0110"; -- address = rr-address
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= DEC_RAM; -- decrement operation
+ s_adr_mux <= "0110"; -- address = rr-address
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_DEC_D => -- DEC direct
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ alu_cmd_o <= DEC_RAM; -- decrement operation
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_DEC_ATRI => -- DEC @Ri
+ if state=FETCH then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= DEC_RAM; -- decrement operation
+ s_adr_mux <= "0111"; -- address = ri-address
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_DIV_AB => -- DIV AB
+ if state=FETCH then
+ s_adr_mux <= "1100"; -- adress of B register
+ alu_cmd_o <= DIV_ACC_RAM; -- divison operation
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_adr_mux <= "1100"; -- adress of B register
+ alu_cmd_o <= DIV_ACC_RAM; -- divison operation
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_adr_mux <= "1100"; -- adress of B register
+ s_regs_wr_en <= "111"; -- write ACC,B,OV,CY(special operation)
+ alu_cmd_o <= DIV_ACC_RAM; -- divison operation
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_DJNZ_RR => -- DJNZ Rr, rel
+ if state=FETCH then
+ s_adr_mux <= "0110"; -- address = rr-address
+ s_help_en <= "0100"; -- save Rr-adress
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= DEC_RAM; -- decrement operation
+ if unsigned(aludata_i) /= 0 then
+ s_adr_mux <= "1010"; -- address = rr-address
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0010"; -- add relativ adress to PC
+ else
+ s_adr_mux <= "1010"; -- address = rr-address
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ end if;
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_DJNZ_D => -- DJNZ direct, rel
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_help_en <= "0001"; -- save address
+ s_adr_mux <= "1000"; -- address = rom_data
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ alu_cmd_o <= DEC_RAM; -- decrement operation
+ if unsigned(aludata_i) /= 0 then
+ s_adr_mux <= "1010"; -- address = help
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0010"; -- add relativ adress to PC
+ else
+ s_adr_mux <= "1010"; -- address = help
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ end if;
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_INC_A => -- INC A
+ alu_cmd_o <= INC_ACC; -- increment operation
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_INC_RR => -- INC Rr
+ if state=FETCH then
+ s_adr_mux <= "0110"; -- address = rr-address
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= INC_RAM; -- increment operation
+ s_adr_mux <= "0110"; -- address = rr-address
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_INC_D => -- INC direct
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ alu_cmd_o <= INC_RAM; -- increment operation
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_INC_ATRI => -- INC @Ri
+ if state=FETCH then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= INC_RAM; -- increment operation
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_INC_DPTR => -- INC DPTR
+ if state=FETCH then
+ s_adr_mux <= "1101"; -- adress of DPL
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= INC_RAM; -- increment operation
+ s_help_en <= "0010"; -- help = aludata_i
+ s_adr_mux <= "1101"; -- adress of DPL
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "1110"; -- adress of DPH
+ s_nextstate <= EXEC3;
+ elsif state=EXEC3 then
+ if s_help=conv_unsigned(0,8) then
+ alu_cmd_o <= INC_RAM; -- increment operation
+ s_adr_mux <= "1110"; -- adress of DPH
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ else
+ end if;
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_JB => -- JB bit, rel
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- bit adress = rom_data_i
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ if s_bit_data = '1' then
+ s_pc_inc_en <= "0010"; -- add relativ adress to PC
+ else
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ end if;
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_JBC => -- JBC bit, rel
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- bit adress = rom_data_i
+ s_help_en <= "0001"; -- s_help = rom_data_i
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "1010"; -- s_adr = s_help
+ s_bdata_mux <= "0000"; -- s_bdata = 0
+ s_regs_wr_en <= "110"; -- write one bit
+ if s_bit_data = '1' then
+ s_pc_inc_en <= "0010"; -- add relativ adress to PC
+ else
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ end if;
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_JC => -- JC rel
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ if cy = '1' then
+ s_pc_inc_en <= "0010"; -- add relativ adress to PC
+ else
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ end if;
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_JMP_A_DPTR => -- JMP @A+DPTR
+ s_pc_inc_en <= "0101"; -- PC = ACC + DPTR
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_JNB => -- JNB bit, rel
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- bit adress = rom_data_i
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ if s_bit_data = '0' then
+ s_pc_inc_en <= "0010"; -- add relativ adress to PC
+ else
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ end if;
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_JNC => -- JNC rel
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ if cy = '0' then
+ s_pc_inc_en <= "0010"; -- add relativ adress to PC
+ else
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ end if;
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_JNZ => -- JNZ rel
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ if unsigned(acc) /= conv_unsigned(0,8) then
+ s_pc_inc_en <= "0010"; -- add relativ adress to PC
+ else
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ end if;
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_JZ => -- JZ rel
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ if unsigned(acc) = conv_unsigned(0,8) then
+ s_pc_inc_en <= "0010"; -- add relativ adress to PC
+ else
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ end if;
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_LCALL => -- LCALL addr16
+ if state=FETCH then
+ s_regs_wr_en <= "001"; -- increment stackpointer
+ s_help16_en <= "01"; -- s_help16 <= pc + 3
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_help_en <= "0001"; -- help <= rom_data_i
+ s_data_mux <= "1100"; -- data <= help16(7 downto 0)
+ s_adr_mux <= "0101"; -- s_adr <= sp
+ s_regs_wr_en <= "101"; -- write one byte and increment SP
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_data_mux <= "1101"; -- data = help16(15 downto 8)
+ s_adr_mux <= "0101"; -- s_adr <= sp
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0111"; -- load program counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_LJMP => -- LJMP addr16
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_help_en <= "0001"; -- help = rom_data_i
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_pc_inc_en <= "0111"; -- load program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_A_RR => -- MOV A,Rr
+ if state=FETCH then
+ s_adr_mux <= "0110"; -- address = rr-address
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_data_mux <= "0100"; -- data = s_reg_data
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+ when IC_MOV_A_D => -- MOV A, direct
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_data_mux <= "0100"; -- data = s_reg_data
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_A_ATRI => -- MOV A,@Ri
+ if state=FETCH then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_data_mux <= "0100"; -- data = s_reg_data
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_A_DATA => -- MOV A, #DATA
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_data_mux <= "0101"; -- data = rom_data_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_RR_A => -- MOV Rr,A
+ s_adr_mux <= "0110"; -- address = rr-address
+ s_data_mux <= "0110"; -- data = ACC
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_RR_D => -- MOV Rr, direct
+ if state=FETCH then
+ s_help_en <= "0100"; -- save Rr-adress in help
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "1010"; -- address = help
+ s_data_mux <= "0100"; -- data = s_reg_data
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- do nothing with program counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_RR_DATA => -- MOV Rr,#data
+ if state=FETCH then
+ s_help_en <= "0100"; -- save Rr-adress in help
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1010"; -- address = help
+ s_data_mux <= "0101"; -- data = rom_data_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- do nothing with program counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_D_A => -- MOV direct, A
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_data_mux <= "0110"; -- data = ACC
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ -------------------------------------------------------------------
+
+ when IC_MOV_D_RR => -- MOV direct, Rr
+ if state=FETCH then
+ s_adr_mux <= "0110"; -- address = rr-address
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_data_mux <= "0100"; -- data = s_reg_data
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- do nothing with program counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_D_D => -- MOV direct, direct
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_data_mux <= "0100"; -- data = s_reg_data
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_D_ATRI => -- MOV direct ,@Ri
+ if state=FETCH then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_data_mux <= "0100"; -- data = s_reg_data
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_D_DATA => -- MOV direct, #data
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_help_en <= "0001"; -- save direct adress
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "1010"; -- address = help
+ s_data_mux <= "0101"; -- data = rom_data_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_ATRI_A => -- MOV @Ri,A
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_data_mux <= "0110"; -- data = ACC
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_ATRI_D => -- MOV @Ri, direct
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_data_mux <= "0100"; -- data = s_reg_data
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_ATRI_DATA => -- MOV @Ri,#data
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_data_mux <= "0101"; -- data = rom_data_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOVC_A_ATDPTR => -- MOVC A, @A+DPTR
+ if state=FETCH then
+ s_help16_en <= "11"; -- save PC+1 in help16
+ s_pc_inc_en <= "0101"; -- PC = A+DPTR
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_data_mux <= "0101"; -- data = rom_data_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0110"; -- PC = help16
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOVC_A_ATPC => -- MOVC A, @A+PC
+ if state=FETCH then
+ s_help16_en <= "11"; -- save PC+1 in help16
+ s_pc_inc_en <= "1001"; -- PC = A+PC+1
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_data_mux <= "0101"; -- data = rom_data_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0110"; -- PC = help16
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOVX_A_ATRI => -- MOVX A, @RI
+ if state=FETCH then
+ s_adrx_mux <= "10"; -- external adress = Ri
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_data_mux <= "1111"; -- data = datax_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOVX_A_ATDPTR => -- MOVX A, @DPTR
+ if state=FETCH then
+ s_adrx_mux <= "01"; -- external adress = DPTR
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_data_mux <= "1111"; -- data = datax_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOVX_ATRI_A => -- MOVX @RI, A
+ s_adrx_mux <= "10"; -- external adress = Ri
+ s_wrx_mux <= '1';
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOVX_ATDPTR_A => -- MOVX @DPTR, A
+ s_adrx_mux <= "01"; -- external adress = DPTR
+ s_wrx_mux <= '1';
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_C_BIT => -- MOV C, bit
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_bdata_mux <= "0111"; -- bdata = s_bit_data
+ s_regs_wr_en <= "110"; -- write one bit (automatic CY-address)
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_BIT_C => -- MOV bit,C
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_bdata_mux <= "1000"; -- bdata = cy
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MOV_DPTR_DATA => -- MOV DPTR, #data16
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1110"; -- adress of DPH
+ s_data_mux <= "0101"; -- data = rom_data_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "1101"; -- adress of DPL
+ s_data_mux <= "0101"; -- data = rom_data_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_MUL_AB => -- MUL AB
+ if state=FETCH then
+ s_adr_mux <= "1100"; -- adress of B register
+ alu_cmd_o <= MUL_ACC_RAM; -- divison operation
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_adr_mux <= "1100"; -- adress of B register
+ alu_cmd_o <= MUL_ACC_RAM; -- divison operation
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_adr_mux <= "1100"; -- adress of B register
+ s_regs_wr_en <= "111"; -- write ACC,B,OV,CY (special operation)
+ alu_cmd_o <= MUL_ACC_RAM; -- divison operation
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_NOP => -- NOP
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_ORL_A_RR => -- ORL A,Rr
+ if state=FETCH then
+ s_adr_mux <= "0110"; -- address = rr-address
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= OR_RAM_ACC; -- OR command (ACC v RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+ when IC_ORL_A_D => -- ORL A, direct
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ alu_cmd_o <= OR_RAM_ACC; -- OR command (ACC v RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+ when IC_ORL_A_ATRI => -- ORL A,@Ri
+ if state=FETCH then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= OR_RAM_ACC; -- OR command (ACC v RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+ when IC_ORL_A_DATA => -- ORL A, data
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= OR_ROM_ACC; -- OR command (ACC v ROM_DATA_I)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+ when IC_ORL_D_A => -- ORL direct, A
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ alu_cmd_o <= OR_RAM_ACC; -- OR command (ACC v RAM_DATA)
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ORL_D_DATA => -- ORL direct, DATA
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_help_en <= "0001"; -- save rom_data_i
+ s_adr_mux <= "1000";
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ alu_cmd_o <= OR_ROM_RAM; -- OR command (ROM_DATA_I v RAM_DATA)
+ s_adr_mux <= "1010"; -- address = help
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ORL_C_BIT => -- ORL C, bit
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_bdata_mux <= "1001"; -- bdata = s_bit_data or cy
+ s_regs_wr_en <= "110"; -- write one bit (autmatically CY)
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_ORL_C_NBIT => -- ORL C, /bit
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_bdata_mux <= "1010"; -- bdata = not (s_bit_data or cy)
+ s_regs_wr_en <= "110"; -- write one bit (autmatically CY)
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_POP => -- POP direct
+ if state=FETCH then
+ s_adr_mux <= "0101"; -- address = SP
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_data_mux <= "0100"; -- data = s_reg_data
+ s_regs_wr_en <= "101"; -- write one byte and decrement SP
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_PUSH => -- PUSH direct
+ if state=FETCH then
+ s_regs_wr_en <= "001"; -- increment SP
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "0101"; -- address = SP
+ s_data_mux <= "0100"; -- data = s_reg_data
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_RET => -- RET
+ if state=FETCH then
+ s_adr_mux <= "0101"; -- adress = SP
+ s_regs_wr_en <= "001"; -- decrement stackpointer
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_help_en <= "0011"; -- save data for PC-high
+ s_adr_mux <= "0101"; -- adress = SP
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_regs_wr_en <= "001"; -- decrement stackpointer
+ s_pc_inc_en <= "1000"; -- reload program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_RETI => -- RETI
+ if state=FETCH then
+ s_adr_mux <= "0101"; -- adress = SP
+ s_regs_wr_en <= "001"; -- decrement stackpointer
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_help_en <= "0011"; -- save data for PC-high
+ s_adr_mux <= "0101";
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ if s_inthigh='1' then -- an high priority interrupt is ending
+ s_inthigh_en <= '1';
+ s_inthigh_d <= '0';
+ s_ext0isrh_d <= '0';
+ s_ext0isrh_en <= '1';
+ s_ext1isrh_d <= '0';
+ s_ext1isrh_en <= '1';
+ elsif s_intlow='1' then -- an low priority interrupt is ending
+ s_intlow_en <= '1';
+ s_intlow_d <= '0';
+ s_ext0isr_d <= '0';
+ s_ext0isr_en <= '1';
+ s_ext1isr_d <= '0';
+ s_ext1isr_en <= '1';
+ else -- no interrupt was started
+ NULL; -- => normal RET command
+ end if;
+ s_regs_wr_en <= "001"; -- decrement stackpointer
+ s_pc_inc_en <= "1000"; -- reload program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_RL_A => -- RL A
+ alu_cmd_o <= RL_ACC; -- rotate ACC left
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_RLC_A => -- RLC A
+ alu_cmd_o <= RLC_ACC; -- rotate ACC with CY left
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "111"; -- write ACC and CY (special operation)
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_RR_A => -- RR A
+ alu_cmd_o <= RR_ACC; -- rotate ACC right
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_RRC_A => -- RRC A
+ alu_cmd_o <= RRC_ACC; -- rotate ACC with CY right
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "111"; -- write ACC and CY (special operation)
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_SETB_C => -- SETB C
+ s_adr_mux <= "1011"; -- adress of CY
+ s_bdata_mux <= "1011"; -- bdata = 1
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_SETB_BIT => -- SETB bit
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- byte adress
+ s_bdata_mux <= "1011"; -- bdata = 1
+ s_regs_wr_en <= "110"; -- write one bit
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_SJMP => -- SJMP rel
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_pc_inc_en <= "0010"; -- load program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_SUBB_A_RR => -- SUBB A,Rr
+ if state=FETCH then
+ s_adr_mux <= "0110"; -- address = rr-address
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= SUB_ACC_RAM; -- subtraction command (ACC - RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+ when IC_SUBB_A_D => -- SUBB A, direct
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ alu_cmd_o <= SUB_ACC_RAM; -- subtraction command (ACC - RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+ when IC_SUBB_A_ATRI => -- SUBB A,@Ri
+ if state=FETCH then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= SUB_ACC_RAM; -- subtraction command (ACC - RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_SUBB_A_DATA => -- SUBB A, DATA
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "011"; -- write ACC and CY,OV,AC
+ alu_cmd_o <= SUB_ACC_ROM; -- subtraction command (ACC-ROM_DATA_I)
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_SWAP_A => -- SWAP A
+ s_data_mux <= "0111"; -- data = acc(3 downto 0) acc(7 downto 4)
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+
+ ---------------------------------------------------------------------
+
+ when IC_XCH_A_RR => -- XCH A,Rr
+ if state=FETCH then
+ s_adr_mux <= "0110"; -- address = rr-address
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "0110"; -- address = rr-address
+ s_help_en <= "0011"; -- help = s_reg_data
+ s_data_mux <= "0110"; -- data = ACC
+ s_regs_wr_en <= "100"; -- write ACC
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_data_mux <= "1000"; -- data = help
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_XCH_A_D => -- XCH A, direct
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "1000"; -- address = rom_data_i
+ s_help_en <= "0011"; -- help = s_reg_data
+ s_data_mux <= "0110"; -- data = ACC
+ s_regs_wr_en <= "100"; -- write one byte
+ s_nextstate <= EXEC3;
+ elsif state=EXEC3 then
+ s_data_mux <= "1000"; -- data = help;
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_XCH_A_ATRI => -- XCH A,@Ri
+ if state=FETCH then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_help_en <= "0011"; -- help = s_reg_data
+ s_data_mux <= "0110"; -- data = ACC
+ s_regs_wr_en <= "100"; -- write one byte
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_data_mux <= "1000"; -- data = help;
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_XCHD_A_ATRI => -- XCHD A,@Ri
+ if state=FETCH then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_help_en <= "1010"; -- s_help = acc
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_data_mux <= "1010"; -- data = acc(7..4) & s_reg_data(3..0)
+ s_regs_wr_en <= "010"; -- write ACC
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_data_mux <= "1001"; -- data = s_reg_data(7..4) & s_help(3..0)
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_XRL_A_RR => -- XRL A,Rr
+ if state=FETCH then
+ s_adr_mux <= "0110"; -- address = rr-address
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= XOR_RAM_ACC; -- XOR command (ACC v RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+ when IC_XRL_A_D => -- XRL A, direct
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000";
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ alu_cmd_o <= XOR_RAM_ACC; -- XOR command (ACC v RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+ when IC_XRL_A_ATRI => -- XRL A,@Ri
+ if state=FETCH then
+ s_adr_mux <= "0111"; -- address = Ri-register
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ alu_cmd_o <= XOR_RAM_ACC; -- XOR command (ACC v RAM_DATA)
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+ when IC_XRL_A_DATA => -- XRL A, data
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "010"; -- write ACC
+ alu_cmd_o <= XOR_ROM_ACC; -- XOR command (ACC v ROM_DATA_I)
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+ when IC_XRL_D_A => -- XRL direct, A
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_adr_mux <= "1000";
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "1000";
+ s_data_mux <= "0011"; -- data = aludata_i
+ s_regs_wr_en <= "100"; -- write one byte
+ alu_cmd_o <= XOR_RAM_ACC; -- XOR command (ACC v RAM_DATA)
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when IC_XRL_D_DATA => -- XRL direct, DATA
+ if state=FETCH then
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC1;
+ elsif state=EXEC1 then
+ s_help_en <= "0001";
+ s_adr_mux <= "1000";
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= EXEC2;
+ elsif state=EXEC2 then
+ s_adr_mux <= "1010";
+ s_data_mux <= "0011"; -- data = aludata_i
+ alu_cmd_o <= XOR_ROM_RAM; -- XOR command (ROM_DATA_I v RAM_DATA)
+ s_regs_wr_en <= "100"; -- write one byte
+ s_pc_inc_en <= "0001"; -- increment program-counter
+ s_nextstate <= FETCH;
+ end if;
+
+ ---------------------------------------------------------------------
+
+ when others =>
+ s_nextstate <= FETCH;
+ end case;
+ end if;
+ end if;
+ end process p_state;
+
+end rtl;
diff --git a/testsuite/synth/issue2273/control_fsm_rtl_cfg.vhd b/testsuite/synth/issue2273/control_fsm_rtl_cfg.vhd
new file mode 100644
index 000000000..1115d26c5
--- /dev/null
+++ b/testsuite/synth/issue2273/control_fsm_rtl_cfg.vhd
@@ -0,0 +1,69 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Helmut Mayrhofer
+--
+-- Filename: control_fsm_rtl_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Decode instruction and execute it. Pure combinational
+-- descripton of the finite state machine.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration control_fsm_rtl_cfg of control_fsm is
+ for rtl
+ end for;
+end control_fsm_rtl_cfg;
diff --git a/testsuite/synth/issue2273/control_mem_.vhd b/testsuite/synth/issue2273/control_mem_.vhd
new file mode 100644
index 000000000..465e62522
--- /dev/null
+++ b/testsuite/synth/issue2273/control_mem_.vhd
@@ -0,0 +1,206 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Helmut Mayrhofer
+--
+-- Filename: control_mem_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.6 $
+--
+-- Date of Latest Version: $Date: 2006-09-07 09:59:09 $
+--
+--
+-- Description: Describe all sequential funcitonality like read from
+-- special function registers, observe interrupt sources,
+-- write to special function registers, and read or write
+-- to the bit addressable memory area.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+library work;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+use work.mc8051_p.all;
+
+
+entity control_mem is
+
+ port (pc_o : out std_logic_vector(15 downto 0); -- Programmcounter =
+ -- ROM-adress
+ rom_data_i : in std_logic_vector(7 downto 0); -- data input from ROM
+ ram_data_o : out std_logic_vector(7 downto 0); -- data output to
+ -- internal RAM
+ ram_data_i : in std_logic_vector(7 downto 0); -- data input from
+ -- internal RAM
+ ram_adr_o : out std_logic_vector(6 downto 0); -- internal RAM-adress
+ reg_data_o : out std_logic_vector(7 downto 0); -- data for ALU
+ ram_wr_o : out std_logic; -- read (0) / write (1)
+ -- internal RAM
+ cy_o : out std_logic_vector(1 downto 0); -- Carry Flag
+ ov_o : out std_logic; -- Overflow Flag
+ ram_en_o : out std_logic; -- RAM-block enable
+ aludata_i : in std_logic_vector (7 downto 0); -- ALU result
+ aludatb_i : in std_logic_vector (7 downto 0); -- 2nd ALU result
+ acc_o : out std_logic_vector (7 downto 0); -- ACC register
+ new_cy_i : in std_logic_vector(1 downto 0); -- CY result of ALU
+ new_ov_i : in std_logic; -- OV result of ALU
+ reset : in std_logic; -- reset signal
+ clk : in std_logic; -- clock signal
+ cen : in std_logic; -- clock enable
+ int0_i : in std_logic_vector(C_IMPL_N_EXT-1 downto 0); -- ext.Int
+ int1_i : in std_logic_vector(C_IMPL_N_EXT-1 downto 0); -- ext.Int
+
+ p0_i : in std_logic_vector(7 downto 0); -- IO-port0
+ p1_i : in std_logic_vector(7 downto 0); -- IO-port1
+ p2_i : in std_logic_vector(7 downto 0); -- IO-port2
+ p3_i : in std_logic_vector(7 downto 0); -- IO-port3
+
+ p0_o : out std_logic_vector(7 downto 0); -- IO-port0
+ p1_o : out std_logic_vector(7 downto 0); -- IO-port1
+ p2_o : out std_logic_vector(7 downto 0); -- IO-port2
+ p3_o : out std_logic_vector(7 downto 0); -- IO-port3
+
+ -- Signals to and from the SIUs
+
+ -- "1" starts serial transmission in SIU
+ all_trans_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ -- RI,SM0,SM1,SM2,REN,TB8
+ all_scon_o : out std_logic_vector(6*C_IMPL_N_SIU-1 downto 0);
+ -- data buffer for SIU
+ all_sbuf_o : out std_logic_vector(8*C_IMPL_N_SIU-1 downto 0);
+ -- baud rate for SIU in PCON
+ all_smod_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ -- RB8, TI, RI of SIU
+ all_scon_i : in std_logic_vector(3*C_IMPL_N_SIU-1 downto 0);
+ -- int. data buffer of SIU
+ all_sbuf_i : in std_logic_vector(8*C_IMPL_N_SIU-1 downto 0);
+
+ -- signals to and from the timer/counters
+
+ -- timer run flag0 of T/C
+ all_tcon_tr0_o : out std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ -- timer run flag1 of T/C
+ all_tcon_tr1_o : out std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ -- TMOD for T/C
+ all_tmod_o : out std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ -- user reload value for T/C
+ all_reload_o : out std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ -- reload enable for T/C
+ all_wt_o : out std_logic_vector(2*C_IMPL_N_TMR-1 downto 0);
+ -- reload target for T/C
+ all_wt_en_o : out std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ -- timer OF flag0 of T/C
+ all_tf0_i : in std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ -- timer OF flag1 of T/C
+ all_tf1_i : in std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ -- count value of T/C
+ all_tl0_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ -- count value of T/C
+ all_tl1_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ -- count value of T/C
+ all_th0_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ -- count value of T/C
+ all_th1_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+
+ -- signals from/to the state-machine
+
+ state_o : out t_state; -- actual state
+ help_o : out std_logic_vector(7 downto 0); -- general help-reg
+ bit_data_o : out std_logic; -- bitdata from regs
+ command_o : out std_logic_vector (7 downto 0); -- actual command
+ inthigh_o : out std_logic; -- high priority int is running
+ intlow_o : out std_logic; -- low priority int is running
+ intpre_o : out std_logic; -- an interrupt must start
+ intpre2_o : out std_logic; -- prepare for interrupt
+ intblock_o : out std_logic; -- interrupt delay at RETI, IE, IP
+ ti_o : out std_logic;
+ ri_o : out std_logic;
+ ie0_o : out std_logic;
+ ie1_o : out std_logic;
+ tf0_o : out std_logic;
+ tf1_o : out std_logic;
+ psw_o : out std_logic_vector(7 downto 0);
+ ie_o : out std_logic_vector(7 downto 0);
+ ip_o : out std_logic_vector(7 downto 0);
+ adrx_o : out std_logic_vector(15 downto 0); -- ext. RAM
+ datax_o : out std_logic_vector(7 downto 0); -- ext. RAM
+ wrx_o : out std_logic; -- ext. RAM
+ memx_o : out std_logic;
+
+ datax_i : in std_logic_vector(7 downto 0); -- ext. RAM
+ pc_inc_en_i : in std_logic_vector (3 downto 0);
+ nextstate_i : in t_state; -- enable signal for state
+ adr_mux_i : in std_logic_vector (3 downto 0);
+ adrx_mux_i : in std_logic_vector (1 downto 0);
+ wrx_mux_i : in std_logic;
+ data_mux_i : in std_logic_vector (3 downto 0);
+ bdata_mux_i : in std_logic_vector (3 downto 0);
+ regs_wr_en_i : in std_logic_vector (2 downto 0);
+ help_en_i : in std_logic_vector (3 downto 0);
+ help16_en_i : in std_logic_vector (1 downto 0);
+ helpb_en_i : in std_logic;
+ inthigh_en_i : in std_logic;
+ intlow_en_i : in std_logic;
+ intpre2_en_i : in std_logic;
+ inthigh_d_i : in std_logic;
+ intlow_d_i : in std_logic;
+ intpre2_d_i : in std_logic;
+ ext0isr_d_i : in std_logic;
+ ext1isr_d_i : in std_logic;
+ ext0isrh_d_i : in std_logic;
+ ext1isrh_d_i : in std_logic;
+ ext0isr_en_i : in std_logic;
+ ext1isr_en_i : in std_logic;
+ ext0isrh_en_i : in std_logic;
+ ext1isrh_en_i : in std_logic);
+
+end control_mem;
diff --git a/testsuite/synth/issue2273/control_mem_rtl.vhd b/testsuite/synth/issue2273/control_mem_rtl.vhd
new file mode 100644
index 000000000..4967a8dfd
--- /dev/null
+++ b/testsuite/synth/issue2273/control_mem_rtl.vhd
@@ -0,0 +1,1148 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Helmut Mayrhofer
+--
+-- Filename: control_mem_rtl.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.11 $
+--
+-- Date of Latest Version: $Date: 2010-03-24 10:20:48 $
+--
+--
+-- Description: Describe all sequential funcitonality like read from
+-- special function registers, observe interrupt sources,
+-- write to special function registers, and read or write
+-- to the bit addressable memory area.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture rtl of control_mem is
+
+
+ type t_gprbit is array (15 downto 0) of unsigned(7 downto 0);
+ subtype muxint is integer range C_IMPL_N_TMR-1 downto 0;
+
+ signal s_help: unsigned (7 downto 0); -- general help-register
+ signal s_help16: unsigned (15 downto 0); -- 16 bit help-register
+ signal s_helpb : std_logic; -- general help-bit
+ signal s_ir: unsigned (7 downto 0); -- reg for saving the command
+ signal gprbit: t_gprbit; -- bitadressable general purpose RAM
+ signal s_r0_b0: unsigned (7 downto 0); -- Register R0 / Bank 0
+ signal s_r1_b0: unsigned (7 downto 0); -- Register R1 / Bank 0
+ signal s_r0_b1: unsigned (7 downto 0); -- Register R0 / Bank 1
+ signal s_r1_b1: unsigned (7 downto 0); -- Register R1 / Bank 1
+ signal s_r0_b2: unsigned (7 downto 0); -- Register R0 / Bank 2
+ signal s_r1_b2: unsigned (7 downto 0); -- Register R1 / Bank 2
+ signal s_r0_b3: unsigned (7 downto 0); -- Register R0 / Bank 3
+ signal s_r1_b3: unsigned (7 downto 0); -- Register R1 / Bank 3
+ signal s_reg_data: unsigned (7 downto 0); -- equals reg_data_o
+ Signal state: t_state; -- actual state
+ signal s_command: std_logic_vector (7 downto 0);
+
+ signal s_pc_inc_en : std_logic_vector (3 downto 0);
+ signal s_regs_wr_en : std_logic_vector (2 downto 0);
+ signal s_data_mux : std_logic_vector (3 downto 0);
+ signal s_bdata_mux : std_logic_vector (3 downto 0);
+ signal s_adr_mux : std_logic_vector (3 downto 0);
+ signal s_adrx_mux : std_logic_vector (1 downto 0);
+ signal s_help_en : std_logic_vector (3 downto 0);
+ signal s_help16_en : std_logic_vector (1 downto 0);
+ signal s_helpb_en : std_logic;
+ signal s_intpre2_d : std_logic;
+ signal s_intpre2_en: std_logic;
+ signal s_intlow_d : std_logic;
+ signal s_intlow_en : std_logic;
+ signal s_inthigh_d : std_logic;
+ signal s_inthigh_en: std_logic;
+ signal s_ext0isr_d : std_logic;
+ signal s_ext0isrh_d : std_logic;
+ signal s_ext1isr_d : std_logic;
+ signal s_ext1isrh_d : std_logic;
+
+ signal s_nextstate : t_state; -- enable signal for state
+
+ signal s_bit_data : std_logic;
+ signal s_intpre: std_logic; -- an interrupt must start
+ signal s_intpre2: std_logic; -- prepare for interrupt
+ signal s_inthigh: std_logic; -- high priority int is running
+ signal s_intlow: std_logic; -- low priority int is running
+ signal s_intblock: std_logic; -- interrupt delay at RETI, IE, IP
+ signal s_intblock_o: std_logic; -- CK, CV: intblock_o signal for internal use
+
+ signal s_int0_edge : t_ext_l;
+ signal s_int1_edge : t_ext_l;
+
+ signal s_tf0_edge : t_tmr_l;
+ signal s_tf1_edge : t_tmr_l;
+ signal s_ri_edge : t_siu_l;
+ signal s_ti_edge : t_siu_l;
+ signal s_smodreg : t_siu_l;
+ signal s_tl0 : t_tmr_us;
+ signal s_tl1 : t_tmr_us;
+ signal s_th0 : t_tmr_us;
+ signal s_th1 : t_tmr_us;
+ signal s_sbufi : t_siu_us;
+ signal s_reload : t_tmr_us;
+ signal s_wt : t_tmr_us2;
+
+ signal s_tf1 : std_logic;
+ signal s_tf0 : std_logic;
+ signal s_ie1 : std_logic;
+ signal s_ie0 : std_logic;
+
+ signal s_ri : std_logic;
+ signal s_ti : std_logic;
+ signal s_rb8 : std_logic;
+ signal s_tb8 : std_logic;
+ signal s_ren : std_logic;
+ signal s_sm2 : std_logic;
+ signal s_sm1 : std_logic;
+ signal s_sm0 : std_logic;
+ signal s_smod : std_logic;
+
+ signal s_int0_h1 : t_ext_l; -- help-bit for edge detection
+ signal s_int0_h2 : t_ext_l;
+ signal s_int0_h3 : t_ext_l;
+ signal s_int1_h1 : t_ext_l;
+ signal s_int1_h2 : t_ext_l;
+ signal s_int1_h3 : t_ext_l;
+
+ signal s_tf0_h1,s_tf0_h2 : t_tmr_l;
+ signal s_tf1_h1,s_tf1_h2 : t_tmr_l;
+ signal s_ri_h1,s_ri_h2 : t_siu_l;
+ signal s_ti_h1,s_ti_h2 : t_siu_l;
+
+ signal s_tsel : muxint;
+ signal s_ssel : muxint;
+
+ signal s_p : std_logic;
+
+ signal s_p0 : std_logic_vector(7 downto 0);
+ signal s_p1 : std_logic_vector(7 downto 0);
+ signal s_p2 : std_logic_vector(7 downto 0);
+ signal s_p3 : std_logic_vector(7 downto 0);
+
+ signal pc: unsigned(15 downto 0); -- program counter register
+ signal pc_comb: unsigned(15 downto 0); -- program counter
+ signal pc_plus1: unsigned(15 downto 0); -- program counter + 1
+ signal pc_plus2: unsigned(15 downto 0); -- program counter + 2
+
+ signal s_data : unsigned(7 downto 0);
+ signal s_adr : unsigned(7 downto 0);
+ signal s_preadr : unsigned(7 downto 0);
+ signal s_bdata : std_logic;
+ signal s_rr_adr : unsigned (7 downto 0);
+ signal s_ri_adr : std_logic_vector (7 downto 0);
+ signal s_ri_data : unsigned (7 downto 0);
+
+ -- 8051 standard special-function-register (SFR)
+
+ signal p0: unsigned(7 downto 0);
+ signal sp: unsigned(7 downto 0);
+ signal dpl: unsigned(7 downto 0);
+ signal dph: unsigned(7 downto 0);
+ signal pcon: unsigned(3 downto 0);
+ signal tcon: t_tmr_lv;
+ signal tmod: t_tmr_us;
+ signal p1: unsigned(7 downto 0);
+ signal scon: t_siu_lv;
+ signal sbuf: t_siu_us;
+ signal p2: unsigned(7 downto 0);
+ signal ie: std_logic_vector(7 downto 0);
+ signal p3: unsigned(7 downto 0);
+ signal ip: std_logic_vector(7 downto 0);
+ signal psw: std_logic_vector(7 downto 0);
+ signal acc: unsigned(7 downto 0);
+ signal b: unsigned(7 downto 0);
+
+ -- 8051 extended special-function-register
+
+ signal tsel: unsigned(7 downto 0); -- select a Timer-Unit
+ signal ssel: unsigned(7 downto 0); -- select a SIU-Unit
+
+ alias CY : std_logic is psw(7);
+ alias AC : std_logic is psw(6);
+ alias OV : std_logic is psw(2);
+ alias EA: std_logic is ie(7);
+ alias ES: std_logic is ie(4);
+ alias ET1: std_logic is ie(3);
+ alias EX1: std_logic is ie(2);
+ alias ET0: std_logic is ie(1);
+ alias EX0: std_logic is ie(0);
+ alias PS0: std_logic is ip(4);
+ alias PT1: std_logic is ip(3);
+ alias PX1: std_logic is ip(2);
+ alias PT0: std_logic is ip(1);
+ alias PX0: std_logic is ip(0);
+
+begin
+
+ -- some simple assignments
+
+ pc_o <= std_logic_vector(pc_comb);
+ pc_plus1 <= pc + conv_unsigned(1,1);
+ pc_plus2 <= pc + conv_unsigned(2,2);
+ ram_adr_o <= std_logic_vector(s_adr(6 downto 0));
+ reg_data_o <= std_logic_vector(s_reg_data);
+ ram_data_o <= std_logic_vector(s_data);
+ acc_o <= std_logic_vector(acc);
+ cy_o(1) <= cy;
+ ov_o <= ov;
+ cy_o(0) <= ac;
+
+ ie_o <= ie;
+ ip_o <= ip;
+ psw_o <= psw;
+ state_o <= state;
+ command_o <= s_command;
+ ri_o <= s_ri;
+ ti_o <= s_ti;
+ help_o <= std_logic_vector(s_help);
+ bit_data_o <= s_bit_data;
+ intpre_o <= s_intpre;
+ intpre2_o <= s_intpre2;
+ inthigh_o <= s_inthigh;
+ intlow_o <= s_intlow;
+ tf1_o <= s_tf1;
+ tf0_o <= s_tf0;
+ ie1_o <= s_ie1;
+ ie0_o <= s_ie0;
+
+ s_pc_inc_en <= pc_inc_en_i;
+ s_nextstate <= nextstate_i;
+ s_adr_mux <= adr_mux_i;
+ s_adrx_mux <= adrx_mux_i;
+ s_data_mux <= data_mux_i;
+ s_bdata_mux <= bdata_mux_i;
+ s_regs_wr_en <= regs_wr_en_i;
+ s_help_en <= help_en_i;
+ s_help16_en <= help16_en_i;
+ s_helpb_en <= helpb_en_i;
+ s_inthigh_en <= inthigh_en_i;
+ s_intlow_en <= intlow_en_i;
+ s_intpre2_en <= intpre2_en_i;
+ s_inthigh_d <= inthigh_d_i;
+ s_intlow_d <= intlow_d_i;
+ s_intpre2_d <= intpre2_d_i;
+ intblock_o <= s_intblock_o; -- CK, CV: assignment of intblock_o output
+
+ s_tsel <= conv_integer(tsel) when tsel < C_IMPL_N_TMR
+ else 0; -- selected timer unit is (not) implemented
+ s_ssel <= conv_integer(ssel) when ssel < C_IMPL_N_SIU
+ else 0; -- selected siu unit is (not) implemented
+
+ for_tmr:
+ for i in 0 to C_IMPL_N_TMR-1 generate
+ all_tcon_tr0_o(i) <= tcon(i)(4);
+ all_tcon_tr1_o(i) <= tcon(i)(6);
+ all_tmod_o((i*8)+7 downto i*8) <= std_logic_vector(tmod(i));
+ s_tl0(i) <= unsigned(all_tl0_i((i*8)+7 downto i*8));
+ s_tl1(i) <= unsigned(all_tl1_i((i*8)+7 downto i*8));
+ s_th0(i) <= unsigned(all_th0_i((i*8)+7 downto i*8));
+ s_th1(i) <= unsigned(all_th1_i((i*8)+7 downto i*8));
+ all_reload_o((i*8)+7 downto i*8) <= std_logic_vector(s_reload(i));
+ all_wt_o((i*2)+1 downto i*2) <= std_logic_vector(s_wt(i));
+ end generate for_tmr;
+
+ s_tf1 <= tcon(s_tsel)(7);
+ s_tf0 <= tcon(s_tsel)(5);
+ s_ie1 <= tcon(s_tsel)(3);
+ s_ie0 <= tcon(s_tsel)(1);
+
+ for_siu:
+ for i in 0 to C_IMPL_N_SIU-1 generate
+ all_scon_o((6*i)+5) <= scon(i)(0); -- RI
+ all_scon_o((6*i)+4) <= scon(i)(7); -- SM0
+ all_scon_o((6*i)+3) <= scon(i)(6); -- SM1
+ all_scon_o((6*i)+2) <= scon(i)(5); -- SM2
+ all_scon_o((6*i)+1) <= scon(i)(4); -- REN
+ all_scon_o(6*i) <= scon(i)(3); -- TB8
+ all_smod_o(i) <= s_smodreg(i); -- SMOD
+ all_sbuf_o((8*i)+7 downto 8*i) <= std_logic_vector(sbuf(i));
+ s_sbufi(i) <= unsigned(all_sbuf_i((i*8)+7 downto i*8));
+ end generate for_siu;
+
+ s_sm0 <= scon(s_ssel)(7);
+ s_sm1 <= scon(s_ssel)(6);
+ s_sm2 <= scon(s_ssel)(5);
+ s_ren <= scon(s_ssel)(4);
+ s_tb8 <= scon(s_ssel)(3);
+ s_rb8 <= all_scon_i((s_ssel*3)+2);
+ s_ti <= scon(s_ssel)(1);
+ s_ri <= scon(s_ssel)(0);
+ s_smod<= s_smodreg(s_ssel);
+
+ p0_o <= std_logic_vector(p0);
+ p1_o <= std_logic_vector(p1);
+ p2_o <= std_logic_vector(p2);
+ p3_o <= std_logic_vector(p3);
+
+ s_p <= acc(7) xor acc(6) xor acc(5) xor acc(4) xor
+ acc(3) xor acc(2) xor acc(1) xor acc(0);
+ -- P should be set, if the count
+ -- of 1 in the acc is even
+
+ s_command <= rom_data_i when state=FETCH
+ else conv_std_logic_vector(s_ir,8);
+
+ s_rr_adr <= unsigned((psw and "00011000") or (rom_data_i
+ and "00000111")); -- calculate registerdirect-adress
+
+ s_ri_adr <= ((psw and "00011000") or (s_command(7 downto 0) and "00000001"));
+
+ datax_o <= std_logic_vector(acc);
+ wrx_o <= wrx_mux_i;
+
+ -- This logic ensures that a pending interrupt is not serviced if
+ -- a) RETI instruction is in progress,
+ -- b) any write to IE or IP register is in progress.
+
+ --s_intblock <= --'1' when (std_logic_vector(s_ir) = RETI) or -- RETI in progress -- CK,CV: new logic for s_intblock inserted
+
+ --(s_regs_wr_en = "100" and -- \
+ -- (conv_integer(s_adr) = 16#B8# or -- | write to
+ -- conv_integer(s_adr) = 16#A8#) and -- | IE or IP
+ -- s_intpre2 = '0') or -- /
+ --(s_regs_wr_en = "110" and -- \
+ -- (s_adr(7 downto 3) = conv_unsigned(21,5) or -- | bit access
+ -- s_adr(7 downto 3) = conv_unsigned(23,5)) and -- | to IE v IP
+ -- s_intpre2 = '0') else '0'; -- /
+
+-- s_intblock <= '1' when (std_logic_vector(s_command) = RETI)
+-- else '0' when (s_nextstate = FETCH and (std_logic_vector(s_command) /= RETI))
+-- else s_intblock_o;
+
+ process(s_command, s_regs_wr_en, s_adr, s_intpre2, s_intblock_o, s_nextstate)
+
+ begin
+
+ if (std_logic_vector(s_command) = RETI) -- ensure single instruction execution after RETI command
+ or
+ (s_regs_wr_en = "100" and -- register access to IP or I
+ (conv_integer(s_adr) = 16#B8# or conv_integer(s_adr) = 16#A8#) and
+ s_intpre2 = '0')
+ or
+ (s_regs_wr_en = "110" and -- bitr access to IE or IP
+ (s_adr(7 downto 3) = conv_unsigned(21,5) or s_adr(7 downto 3) = conv_unsigned(23,5)) and
+ s_intpre2 = '0')
+ then s_intblock <= '1';
+
+ elsif (s_nextstate = FETCH and (std_logic_vector(s_command) /= RETI))
+ then s_intblock <= '0';
+
+ else s_intblock <= s_intblock_o;
+
+ end if;
+ end process; -- CK,CV: end of logic insertion
+
+
+------------------------------------------------------------------------------
+-- purpose: process to read SFR, bitadressable or normal RAM
+-- inputs: s_adr,s_preadr,sp,dpl,dph,pcon,tcon,tmod,all_tl0_i,
+-- all_tl1_i,all_th0_i,all_th1_i,s_p0,s_p1,all_scon_i,all_sbuf_i,
+-- s_p2,ie,s_p3,ip,psw,acc,b,gprbit,ram_data_i
+-- outputs: s_reg_data, s_bit_data
+------------------------------------------------------------------------------
+
+ p_readram : process (s_preadr,s_p0,sp,dpl,dph,pcon,tcon,tmod,s_p1,scon,s_p2,
+ ie,s_p3,ip,psw,acc,b,gprbit,ram_data_i,s_r0_b0,s_r1_b0,
+ s_r0_b1,s_r1_b1,s_r0_b2,s_r1_b2,s_r0_b3,s_r1_b3,
+ s_smod,s_sm0,s_sm1,s_sm2,s_ren,s_tb8,s_rb8,s_ti,s_ri,
+ s_sbufi,s_th1,s_th0,s_ssel,s_tsel,s_tl1,s_tl0,
+ ssel,tsel)
+ begin
+ if s_preadr(7)='1' then
+ case conv_integer(s_preadr) is -- read one byte of a SFR
+ when 16#80# => s_reg_data <= unsigned(s_p0);
+ when 16#81# => s_reg_data <= sp;
+ when 16#82# => s_reg_data <= dpl;
+ when 16#83# => s_reg_data <= dph;
+ when 16#87# =>
+ s_reg_data(7) <= s_smod;
+ s_reg_data(6 downto 4) <= "000";
+ s_reg_data(3 downto 0) <= pcon;
+ when 16#88# => s_reg_data <= unsigned(tcon(s_tsel));
+ when 16#89# => s_reg_data <= unsigned(tmod(s_tsel));
+ when 16#8A# => s_reg_data <= s_tl0(s_tsel);
+ when 16#8B# => s_reg_data <= s_tl1(s_tsel);
+ when 16#8C# => s_reg_data <= s_th0(s_tsel);
+ when 16#8D# => s_reg_data <= s_th1(s_tsel);
+ when 16#8E# => s_reg_data <= tsel;
+ when 16#90# => s_reg_data <= unsigned(s_p1);
+ when 16#98# =>
+ s_reg_data(0) <= s_ri; -- from SCON register
+ s_reg_data(1) <= s_ti; -- from SCON register
+ s_reg_data(2) <= s_rb8; -- read extern input!!!
+ s_reg_data(3) <= s_tb8;
+ s_reg_data(4) <= s_ren;
+ s_reg_data(5) <= s_sm2;
+ s_reg_data(6) <= s_sm1;
+ s_reg_data(7) <= s_sm0;
+ when 16#99# => s_reg_data <= s_sbufi(s_ssel);
+ when 16#9A# => s_reg_data <= ssel;
+ when 16#A0# => s_reg_data <= unsigned(s_p2);
+ when 16#A8# => s_reg_data <= unsigned(ie);
+ when 16#B0# => s_reg_data <= unsigned(s_p3);
+ when 16#B8# => s_reg_data <= unsigned(ip);
+ when 16#D0# => s_reg_data <= unsigned(psw);
+ when 16#E0# => s_reg_data <= acc;
+ when 16#F0# => s_reg_data <= b;
+ when others => s_reg_data <= conv_unsigned(0,8);
+ end case;
+ -- read one byte to bitadressable GPR
+ elsif conv_std_logic_vector(s_preadr(7 downto 4),4)="0010" then
+ s_reg_data <= gprbit(conv_integer(s_preadr(3 downto 0)));
+
+ elsif conv_std_logic_vector(s_preadr,8)="00000000" then
+ s_reg_data <= s_r0_b0; -- read R0 / Bank 0
+ elsif conv_std_logic_vector(s_preadr,8)="00000001" then
+ s_reg_data <= s_r1_b0; -- read R1 / Bank 0
+ elsif conv_std_logic_vector(s_preadr,8)="00001000" then
+ s_reg_data <= s_r0_b1; -- read R0 / Bank 1
+ elsif conv_std_logic_vector(s_preadr,8)="00001001" then
+ s_reg_data <= s_r1_b1; -- read R1 / Bank 1
+ elsif conv_std_logic_vector(s_preadr,8)="00010000" then
+ s_reg_data <= s_r0_b2; -- read R0 / Bank 2
+ elsif conv_std_logic_vector(s_preadr,8)="00010001" then
+ s_reg_data <= s_r1_b2; -- read R1 / Bank 2
+ elsif conv_std_logic_vector(s_preadr,8)="00011000" then
+ s_reg_data <= s_r0_b3; -- read R0 / Bank 3
+ elsif conv_std_logic_vector(s_preadr,8)="00011001" then
+ s_reg_data <= s_r1_b3; -- read R1 / Bank 3
+
+ else -- read on general purpose RAM
+ s_reg_data <= unsigned(ram_data_i);
+ end if;
+
+ if s_preadr(7)='1' then
+ case s_preadr(6 downto 3) is -- read only one bit from a SFR
+ when "0000" => s_bit_data <= s_p0(conv_integer(s_preadr(2 downto 0)));
+ when "0001" =>
+ s_bit_data <= tcon(s_tsel)(conv_integer(s_preadr(2 downto 0)));
+ when "0010" => s_bit_data <= s_p1(conv_integer(s_preadr(2 downto 0)));
+ when "0011" =>
+ if conv_integer(s_preadr(2 downto 0))=2 then
+ s_bit_data <= s_rb8;
+ else
+ s_bit_data <= scon(s_ssel)(conv_integer(s_preadr(2 downto 0)));
+ end if;
+ when "0100" => s_bit_data <= s_p2(conv_integer(s_preadr(2 downto 0)));
+ when "0101" => s_bit_data <= ie(conv_integer(s_preadr(2 downto 0)));
+ when "0110" => s_bit_data <= s_p3(conv_integer(s_preadr(2 downto 0)));
+ when "0111" => s_bit_data <= ip(conv_integer(s_preadr(2 downto 0)));
+ when "1010" => s_bit_data <= psw(conv_integer(s_preadr(2 downto 0)));
+ when "1100" => s_bit_data <= acc(conv_integer(s_preadr(2 downto 0)));
+ when "1110" => s_bit_data <= b(conv_integer(s_preadr(2 downto 0)));
+ when others => s_bit_data <= '0';
+ end case;
+ else -- read one bit from bitadressable GP
+ s_bit_data <= gprbit(conv_integer(s_preadr(6 downto 3)))
+ (conv_integer(s_preadr(2 downto 0)));
+ end if;
+ end process p_readram;
+
+------------------------------------------------------------------------------
+-- detect the rising/falling edge of interupt-sources
+------------------------------------------------------------------------------
+
+for_intext_edge:
+ for i in 0 to C_IMPL_N_EXT-1 generate
+ -- falling edge of int0_i
+ s_int0_edge(i) <= not s_int0_h2(i) and s_int0_h3(i);
+ -- falling edge of int1_i
+ s_int1_edge(i) <= not s_int1_h2(i) and s_int1_h3(i);
+ end generate for_intext_edge;
+
+for_tf_edge:
+ for i in 0 to C_IMPL_N_TMR-1 generate
+ -- on rising edge of tf0_i
+ s_tf0_edge(i) <= s_tf0_h1(i) and not s_tf0_h2(i);
+ -- on rising edge of tf1_i
+ s_tf1_edge(i) <= s_tf1_h1(i) and not s_tf1_h2(i);
+ end generate for_tf_edge;
+
+for_siu_edge:
+ for i in 0 to C_IMPL_N_SIU-1 generate
+ -- on rising edge of RI
+ s_ri_edge(i) <= s_ri_h1(i) and not s_ri_h2(i);
+ -- on rising edge of TI
+ s_ti_edge(i) <= s_ti_h1(i) and not s_ti_h2(i);
+ end generate for_siu_edge;
+
+
+------------------------------------------------------------------------------
+-- purpose: write some help-regs for detecting the falling/rising edge
+-- of interupt-sources
+-- inputs: clk,reset,int0_i,int1_i,all_tf0_i,all_tf1_i,all_scon_i,
+-- s_tf0_h1,s_tf1_h1,s_ri_h1,s_ti_h1
+-- outputs: s_int0_h1,s_int0_h2,s_int0_h3,s_int1_h1,s_int1_h2,s_int1_h3,
+-- s_tf0_h1,s_tf0_h2
+-- s_tf1_h1,s_tf1_h2,s_ri_h1,s_ri_h2,s_ti_h1,s_ti_h2
+------------------------------------------------------------------------------
+
+ iep: process (clk,cen,reset)
+
+ begin -- process iep
+
+ -- activities triggered by asynchronous reset
+ if reset = '1' then
+ s_int0_h1 <= (others => '1');
+ s_int0_h2 <= (others => '1');
+ s_int0_h3 <= (others => '1');
+ s_int1_h1 <= (others => '1');
+ s_int1_h2 <= (others => '1');
+ s_int1_h3 <= (others => '1');
+ s_tf0_h1 <= (others => '0');
+ s_tf0_h2 <= (others => '0');
+ s_tf1_h1 <= (others => '0');
+ s_tf1_h2 <= (others => '0');
+ s_ri_h1 <= (others => '0');
+ s_ri_h2 <= (others => '0');
+ s_ti_h1 <= (others => '0');
+ s_ti_h2 <= (others => '0');
+ s_intblock_o <= '0'; -- CK, CV: changed s_inblock_o to s_intblock_o for internal use
+ -- activities triggered by rising edge of clock
+ elsif clk'event and clk = '1' and cen = '1' then
+ s_intblock_o <= s_intblock; -- CK, CV: changed s_inblock_o to s_intblock_o for internal use
+ for i in 0 to C_IMPL_N_EXT-1 loop
+ s_int0_h1(i) <= int0_i(i); -- external INT0
+ s_int0_h2(i) <= s_int0_h1(i);
+ s_int0_h3(i) <= s_int0_h2(i);
+ s_int1_h1(i) <= int1_i(i); -- external INT1
+ s_int1_h2(i) <= s_int1_h1(i);
+ s_int1_h3(i) <= s_int1_h2(i);
+ end loop;
+ for i in 0 to C_IMPL_N_TMR-1 loop
+ s_tf0_h1(i) <= all_tf0_i(i); -- TF0 flags
+ s_tf0_h2(i) <= s_tf0_h1(i);
+ s_tf1_h1(i) <= all_tf1_i(i); -- TF1 flags
+ s_tf1_h2(i) <= s_tf1_h1(i);
+ -- all_xxx is a std_logic_vector, s_xxx is a array of std_logic !!!
+ end loop;
+ for i in 0 to C_IMPL_N_SIU-1 loop
+ s_ri_h1(i) <= all_scon_i(i*3); -- RI flag
+ s_ri_h2(i) <= s_ri_h1(i);
+ s_ti_h1(i) <= all_scon_i((i*3)+1); -- TI flag
+ s_ti_h2(i) <= s_ti_h1(i);
+ -- all_xxx is a std_logic_vector, s_xxx is a array of std_logic !!!
+ end loop;
+ end if;
+ end process iep;
+
+------------------------------------------------------------------------------
+-- purpose: check the interupt-sources and start an interupt if necessary
+-- inputs: ie,ip,scon,tcon,s_inthigh,s_intlow,s_ti,s_ri,s_ie0,
+-- s_ie1,s_tf0,s_tf1
+-- outputs: s_intpre
+------------------------------------------------------------------------------
+
+ intpre : process (ie,ip,scon,tcon,s_inthigh,s_intlow,s_ti,s_ri,s_ie0,
+ s_ie1,s_tf0,s_tf1)
+ begin
+ if (EA='1' and (EX0='1' or ET0='1' or EX1='1' or ET1='1' or ES='1')) then
+ if s_inthigh='1' then -- interrupt with high priority is running
+ s_intpre <= '0';
+ elsif s_intlow='1' then -- interrupt with low priority is running
+ if ((PX0 and EX0 and s_ie0) or
+ (PT0 and ET0 and s_tf0) or
+ (PX1 and EX1 and s_ie1) or
+ (PT1 and ET1 and s_tf1) or
+ (PS0 and ES and (s_ri or s_ti)))='1' then
+ s_intpre <= '1'; -- a second interrupt must start
+ else
+ s_intpre <= '0';
+ end if;
+ else -- no interrupt is running
+ if ((EX0 and s_ie0) or
+ (ET0 and s_tf0) or
+ (EX1 and s_ie1) or
+ (ET1 and s_tf1) or
+ (ES and (s_ri or s_ti)))='1' then
+ s_intpre <= '1'; -- an interrupt must start
+ else
+ s_intpre <= '0';
+ end if;
+ end if;
+ else -- no interrupt must be carried out
+ s_intpre <= '0';
+ end if;
+ end process intpre;
+
+------------------------------------------------------------------------------
+-- purpose: this are the main-multiplexer for reading and writing regs
+-- inputs: s_data_mux,pc,aludata_i,s_reg_data,rom_data_i,acc,
+-- s_bdata_mux,s_bit_data,psw,new_cy_i,s_helpb,sp,s_rr_adr,
+-- s_ri_data,s_help,s_adr_mux,s_adr,s_regs_wr_en,pc_plus2,
+-- s_help16,s_ri_adr,s_r0_b0,s_r1_b0,s_r0_b1,s_r1_b1,
+-- s_r0_b2,s_r1_b2,s_r0_b3,s_r1_b3
+-- outputs: s_data,s_bdata,s_adr,s_ri_data,ram_wr_o
+------------------------------------------------------------------------------
+
+ p_multiplexer : process (s_data_mux,pc,aludata_i,s_reg_data,rom_data_i,acc,
+ s_bdata_mux,s_bit_data,psw,new_cy_i,s_helpb,sp,s_rr_adr,
+ s_ri_data,s_help,s_adr_mux,s_adr,s_regs_wr_en,pc_plus2,
+ s_help16,s_ri_adr,s_r0_b0,s_r1_b0,s_r0_b1,s_r1_b1,
+ s_r0_b2,s_r1_b2,s_r0_b3,s_r1_b3,s_adrx_mux,dph,dpl,
+ datax_i)
+ begin
+ case s_data_mux is
+ when "0000" => s_data <= conv_unsigned(0,8);
+ when "0001" => s_data <= pc(7 downto 0);
+ when "0010" => s_data <= pc(15 downto 8);
+ when "0011" => s_data <= unsigned(aludata_i);
+ when "0100" => s_data <= s_reg_data;
+ when "0101" => s_data <= unsigned(rom_data_i);
+ when "0110" => s_data <= acc;
+ when "0111" =>
+ s_data(7 downto 4) <= acc(3 downto 0);
+ s_data(3 downto 0) <= acc(7 downto 4);
+ when "1000" => s_data <= s_help;
+ when "1001" =>
+ s_data(7 downto 4) <= s_reg_data(7 downto 4);
+ s_data(3 downto 0) <= s_help(3 downto 0);
+ when "1010" =>
+ s_data(7 downto 4) <= acc(7 downto 4);
+ s_data(3 downto 0) <= s_reg_data(3 downto 0);
+ when "1100" => s_data <= s_help16(7 downto 0);
+ when "1101" => s_data <= s_help16(15 downto 8);
+ when "1110" => s_data <= pc_plus2(7 downto 0);
+ when "1111" => s_data <= unsigned(datax_i);
+ when others => s_data <= conv_unsigned(0,8);
+ end case;
+
+ case s_bdata_mux is
+ when "0000" => s_bdata <= '0';
+ when "0001" => s_bdata <= s_bit_data and cy;
+ when "0010" => s_bdata <= not(s_bit_data) and cy;
+ when "0011" => s_bdata <= new_cy_i(1);
+ when "0100" => s_bdata <= s_helpb;
+ when "0101" => s_bdata <= not cy;
+ when "0110" => s_bdata <= not s_bit_data;
+ when "0111" => s_bdata <= s_bit_data;
+ when "1000" => s_bdata <= cy;
+ when "1001" => s_bdata <= s_bit_data or cy;
+ when "1010" => s_bdata <= not(s_bit_data) or cy;
+ when "1011" => s_bdata <= '1';
+ when others => s_bdata <= '0';
+ end case;
+
+ case s_adr_mux is
+ when "0000" => s_adr <= conv_unsigned(0,8);
+ when "0001" => s_adr <= conv_unsigned(16#89#,8);
+ when "0010" => s_adr <= conv_unsigned(16#8D#,8);
+ when "0011" => s_adr <= conv_unsigned(16#8B#,8);
+ when "0100" => s_adr <= conv_unsigned(16#8F#,8);
+ when "0101" => s_adr <= sp;
+ when "0110" => s_adr <= s_rr_adr;
+ when "0111" => s_adr <= s_ri_data;
+ when "1000" => s_adr <= unsigned(rom_data_i);
+ when "1001" => s_adr <= s_reg_data;
+ when "1010" => s_adr <= s_help ;
+ when "1011" => s_adr <= conv_unsigned(16#D7#,8);
+ when "1100" => s_adr <= conv_unsigned(16#F0#,8);
+ when "1101" => s_adr <= conv_unsigned(16#82#,8);
+ when "1110" => s_adr <= conv_unsigned(16#83#,8);
+ when "1111" => s_adr <= sp + conv_unsigned(1,1);
+ when others => s_adr <= conv_unsigned(0,8);
+ end case;
+
+ case s_adrx_mux is
+ --when "00" => adrx_o <= (others => '0');
+ when "01" =>
+ adrx_o(15 downto 8) <= std_logic_vector(dph);
+ adrx_o(7 downto 0) <= std_logic_vector(dpl);
+ memx_o <= '1';
+ when "10" =>
+ adrx_o(15 downto 8) <= (others => '0');
+ adrx_o(7 downto 0) <= std_logic_vector(s_ri_data);
+ memx_o <= '1';
+ when others => adrx_o <= (others => '0'); memx_o <= '0';
+ end case;
+
+ case s_ri_adr is
+ when "00000000" => s_ri_data <= s_r0_b0;
+ when "00000001" => s_ri_data <= s_r1_b0;
+ when "00001000" => s_ri_data <= s_r0_b1;
+ when "00001001" => s_ri_data <= s_r1_b1;
+ when "00010000" => s_ri_data <= s_r0_b2;
+ when "00010001" => s_ri_data <= s_r1_b2;
+ when "00011000" => s_ri_data <= s_r0_b3;
+ when "00011001" => s_ri_data <= s_r1_b3;
+ when others => s_ri_data <= conv_unsigned(0,8);
+ end case;
+
+ if ((s_regs_wr_en="100") or (s_regs_wr_en="101")) then -- write one byte
+ if ((s_adr(7)='1') or -- SFR
+ (conv_std_logic_vector(s_adr(7 downto 4),4)="0010") -- bitadressable
+ or ((std_logic_vector(s_adr) AND "11100110") = "00000000")) -- R0,R1
+ then
+ ram_wr_o <= '0';
+ else
+ ram_wr_o <= '1'; -- to RAM-block
+ end if;
+ else
+ ram_wr_o <= '0';
+ end if;
+ end process p_multiplexer;
+
+------------------------------------------------------------------------------
+-- purpose: writes internal registers, on which the user have no
+-- direct access
+-- inputs: reset,clk,s_nextstate,state,s_help_en,
+-- rom_data_i,aludata_i,s_reg_data,s_rr_adr,new_cy_i
+-- outputs: state,s_ir,s_help,s_help16,s_helpb,s_intpre2,s_intlow,
+-- s_inthigh,s_preadr
+------------------------------------------------------------------------------
+
+ p_wr_internal_reg : process (reset,cen,clk)
+ begin
+ if reset='1' then
+ state <= STARTUP;
+ s_ir <= conv_unsigned(0,8);
+ s_help <= conv_unsigned(0,8);
+ s_help16 <= conv_unsigned(0,16);
+ s_helpb <= '0';
+ s_intpre2 <= '0';
+ s_intlow <= '0';
+ s_inthigh <= '0';
+ s_preadr <= conv_unsigned(0,8);
+ pc <= conv_unsigned(0,16);
+ s_p0 <= "11111111";
+ s_p1 <= "11111111";
+ s_p2 <= "11111111";
+ s_p3 <= "11111111";
+ s_ext0isr_d <= '0';
+ s_ext0isrh_d <= '0';
+ s_ext1isr_d <= '0';
+ s_ext1isrh_d <= '0';
+ else
+ if Rising_Edge(clk) and cen='1' then
+
+ state <= s_nextstate; -- update current state
+
+ if state=FETCH then
+ s_ir <= unsigned(rom_data_i); -- save OP-Code in IR
+ end if;
+
+ case s_help_en is
+ when "0000" => NULL;
+ when "0001" => s_help <= unsigned(rom_data_i);
+ when "0010" => s_help <= unsigned(aludata_i);
+ when "0011" => s_help <= s_reg_data;
+ when "0100" => s_help <= s_rr_adr;
+ when "0101" => s_help <= conv_unsigned(16#03#,8);
+ when "0110" => s_help <= conv_unsigned(16#0B#,8);
+ when "0111" => s_help <= conv_unsigned(16#13#,8);
+ when "1000" => s_help <= conv_unsigned(16#1B#,8);
+ when "1001" => s_help <= conv_unsigned(16#23#,8);
+ when "1010" => s_help <= acc;
+ when others => NULL;
+ end case;
+
+ case s_help16_en is
+ when "00" => NULL;
+ when "01" => s_help16 <= pc + conv_unsigned(3,2);
+ when "10" => s_help16 <= pc_plus2;
+ when "11" => s_help16 <= pc_plus1;
+ when others => NULL;
+ end case;
+
+ case s_helpb_en is
+ when '0' => NULL;
+ when '1' => s_helpb <= new_cy_i(1);
+ when others => NULL;
+ end case;
+
+ if s_intpre2_en='1' then -- help-reg for s_intpre
+ s_intpre2 <= s_intpre2_d;
+ else
+ NULL;
+ end if;
+
+ if s_intlow_en='1' then
+ s_intlow <= s_intlow_d;
+ else
+ NULL;
+ end if;
+
+ if s_inthigh_en='1' then
+ s_inthigh <= s_inthigh_d;
+ else
+ NULL;
+ end if;
+
+ if ext0isr_en_i = '1' then
+ s_ext0isr_d <= ext0isr_d_i;
+ end if;
+ if ext1isr_en_i = '1' then
+ s_ext1isr_d <= ext1isr_d_i;
+ end if;
+ if ext0isrh_en_i = '1' then
+ s_ext0isrh_d <= ext0isrh_d_i;
+ end if;
+ if ext1isrh_en_i = '1' then
+ s_ext1isrh_d <= ext1isrh_d_i;
+ end if;
+
+ s_preadr <= s_adr;
+
+ pc <= pc_comb; -- write pc-register
+
+ s_p0 <= p0_i;
+ s_p1 <= p1_i;
+ s_p2 <= p2_i;
+ s_p3 <= p3_i;
+
+ end if;
+ end if;
+ end process p_wr_internal_reg;
+
+------------------------------------------------------------------------------
+-- purpose: calculate the next PC-adress
+-- inputs: s_pc_inc_en,pc_plus1,rom_data_i,s_intpre2,s_help,s_command,
+-- s_help16,s_ir,dph,dpl,acc,s_reg_data,pc
+-- outputs: pc_comb
+------------------------------------------------------------------------------
+
+ p_pc : process (s_pc_inc_en,pc_plus1,rom_data_i,s_help,
+ s_help16,s_ir,dph,dpl,acc,s_reg_data,pc)
+ variable v_dptr: unsigned(15 downto 0);
+ begin
+ v_dptr(15 downto 8) := dph;
+ v_dptr(7 downto 0) := dpl;
+ case s_pc_inc_en is
+ when "0001" => -- increment PC
+ pc_comb <= pc_plus1;
+ when "0010" => -- for relativ jumps and calls
+ pc_comb <= conv_unsigned(pc_plus1 + signed(rom_data_i),16);
+ when "0011" => -- load interrupt vectoradress
+ pc_comb(15 downto 8) <= conv_unsigned(0,8);
+ pc_comb(7 downto 0) <= s_help;
+ when "0100" => -- ACALL and AJMP
+ pc_comb(15 downto 11) <= s_help16(15 downto 11);
+ pc_comb(10 downto 8) <= s_ir(7 downto 5);
+ pc_comb(7 downto 0) <= unsigned(rom_data_i);
+ when "0101" => -- JMP_A_DPTR, MOVC_A_ATDPTR
+ pc_comb <= v_dptr + conv_unsigned(acc,8);
+ when "0110" => -- MOVC
+ pc_comb <= s_help16;
+ when "0111" => -- LJMP, LCALL
+ pc_comb(15 downto 8) <= s_help;
+ pc_comb(7 downto 0) <= unsigned(rom_data_i);
+ when "1000" => -- RET, RETI
+ pc_comb(15 downto 8) <= s_help;
+ pc_comb(7 downto 0) <= s_reg_data;
+ when "1001" => -- MOVC_A_ATPC
+ pc_comb <= pc_plus1 + conv_unsigned(acc,8);
+ when others => pc_comb <= pc;
+ end case;
+ end process p_pc;
+
+------------------------------------------------------------------------------
+-- purpose: write RAM, SFR or bitadressable Registers
+-- inputs: reset,clk
+-- outputs: SFR, gprbit
+------------------------------------------------------------------------------
+
+ p_write_ram : process (reset,clk,cen)
+ begin
+ if reset='1' then
+ ram_en_o <= '0';
+ gprbit(0) <= conv_unsigned(0,8);
+ gprbit(1) <= conv_unsigned(0,8);
+ gprbit(2) <= conv_unsigned(0,8);
+ gprbit(3) <= conv_unsigned(0,8);
+ gprbit(4) <= conv_unsigned(0,8);
+ gprbit(5) <= conv_unsigned(0,8);
+ gprbit(6) <= conv_unsigned(0,8);
+ gprbit(7) <= conv_unsigned(0,8);
+ gprbit(8) <= conv_unsigned(0,8);
+ gprbit(9) <= conv_unsigned(0,8);
+ gprbit(10) <= conv_unsigned(0,8);
+ gprbit(11) <= conv_unsigned(0,8);
+ gprbit(12) <= conv_unsigned(0,8);
+ gprbit(13) <= conv_unsigned(0,8);
+ gprbit(14) <= conv_unsigned(0,8);
+ gprbit(15) <= conv_unsigned(0,8);
+ s_r0_b0 <= conv_unsigned(0,8);
+ s_r1_b0 <= conv_unsigned(0,8);
+ s_r0_b1 <= conv_unsigned(0,8);
+ s_r1_b1 <= conv_unsigned(0,8);
+ s_r0_b2 <= conv_unsigned(0,8);
+ s_r1_b2 <= conv_unsigned(0,8);
+ s_r0_b3 <= conv_unsigned(0,8);
+ s_r1_b3 <= conv_unsigned(0,8);
+ p0 <= conv_unsigned(255,8);
+ sp <= conv_unsigned(7,8);
+ dpl <= conv_unsigned(0,8);
+ dph <= conv_unsigned(0,8);
+ pcon <= conv_unsigned(0,4);
+ tcon <= (others => (others => '0'));
+ tmod <= (others => (others => '0'));
+ tsel <= conv_unsigned(0,8);
+ p1 <= conv_unsigned(255,8);
+ scon <= (others => (others => '0'));
+ s_smodreg <= (others => '0');
+ sbuf <= (others => (others => '0'));
+ ssel <= conv_unsigned(0,8);
+ p2 <= conv_unsigned(255,8);
+ ie <= conv_std_logic_vector(0,8);
+ p3 <= conv_unsigned(255,8);
+ ip <= conv_std_logic_vector(0,8);
+ psw <= conv_std_logic_vector(0,8);
+ acc <= conv_unsigned(0,8);
+ b <= conv_unsigned(0,8);
+ s_reload <= (others => (others => '0'));
+ all_wt_en_o <= (others => '0');
+ s_wt <= (others => (others => '0'));
+ all_trans_o <= (others => '0');
+ else
+ ram_en_o <= '1';
+
+ if Rising_Edge(clk) and cen='1' then
+ all_wt_en_o <= ( others => '0' ); -- default values
+ all_trans_o <= ( others => '0' );
+ psw(0) <= s_p;
+ for i in 0 to C_IMPL_N_TMR-1 loop
+ tcon(i)(3) <= tcon(i)(3) or ((tcon(i)(2) and s_int1_edge(i)) or
+ ((not tcon(i)(2) and not s_int1_h2(i)) and
+ not(s_ext1isr_d or s_ext1isrh_d)));
+ tcon(i)(1) <= tcon(i)(1) or ((tcon(i)(0) and s_int0_edge(i)) or
+ ((not tcon(i)(0) and not s_int0_h2(i)) and
+ not(s_ext0isr_d or s_ext0isrh_d)));
+ tcon(i)(5) <= tcon(i)(5) or s_tf0_edge(i);
+ tcon(i)(7) <= tcon(i)(7) or s_tf1_edge(i);
+ end loop;
+ -- update TF1, TF0 and IE1, IE0 in dependance on the IT flags
+ for i in 0 to C_IMPL_N_SIU-1 loop
+ scon(i)(0) <= scon(i)(0) or s_ri_edge(i);
+ scon(i)(1) <= scon(i)(1) or s_ti_edge(i);
+ end loop;
+
+ case s_regs_wr_en is
+ when "001" => -- inc or dec SP
+
+ if (s_intblock='0' and s_intpre='1' and state=FETCH) or s_intpre2='1' then
+ sp <= sp + conv_unsigned(1,1);
+ else
+ case s_command is
+ when RET | RETI =>
+ sp <= sp - conv_unsigned(1,1);
+ when others =>
+ sp <= sp + conv_unsigned(1,1);
+ end case;
+ end if;
+ when "010" => -- write to ACC
+ acc <= s_data;
+ when "011" => -- write to ACC and PSW
+ acc <= s_data;
+ psw(7) <= new_cy_i(1);
+ psw(6) <= new_cy_i(0);
+ psw(2) <= new_ov_i;
+ when "100" | "101" =>
+ case s_regs_wr_en is -- sp register
+ when "100" =>
+ if conv_integer(s_adr) = 16#81# then
+ sp <= s_data;
+ end if;
+ when "101" =>
+ if (s_intblock='0' and s_intpre='1' and state=FETCH) or s_intpre2='1' then
+ sp <= sp + conv_unsigned(1,1);
+ else
+ if s_command = POP then
+ if (conv_integer(s_adr) = 16#81#) then
+ sp <= s_data;
+ else
+ sp <= sp - conv_unsigned(1, 1);
+ end if;
+ else
+ sp <= sp + conv_unsigned(1, 1);
+ end if;
+ end if;
+ when others => NULL;
+ end case;
+
+ if s_adr(7)='1' then
+ case conv_integer(s_adr) is -- write one byte of a SFR
+ when 16#80# => p0 <= s_data;
+ when 16#82# => dpl <= s_data;
+ when 16#83# => dph <= s_data;
+ when 16#87# =>
+ pcon <= s_data(3 downto 0);
+ s_smodreg(s_ssel) <= s_data(7);
+ when 16#88# => tcon(s_tsel) <= std_logic_vector(s_data);
+ when 16#89# => tmod(s_tsel) <= s_data;
+ when 16#8A# =>
+ s_reload(s_tsel) <= s_data; -- tl0
+ s_wt(s_tsel) <= "00";
+ all_wt_en_o(s_tsel) <= '1';
+ when 16#8B# =>
+ s_reload(s_tsel) <= s_data; -- tl1
+ s_wt(s_tsel) <= "01";
+ all_wt_en_o(s_tsel) <= '1';
+ when 16#8C# =>
+ s_reload(s_tsel) <= s_data; -- th0
+ s_wt(s_tsel) <= "10";
+ all_wt_en_o(s_tsel) <= '1';
+ when 16#8D# =>
+ s_reload(s_tsel) <= s_data; -- th1
+ s_wt(s_tsel) <= "11";
+ all_wt_en_o(s_tsel) <= '1';
+ when 16#8E# => tsel <= s_data;
+ when 16#90# => p1 <= s_data;
+ when 16#98# => scon(s_ssel) <= std_logic_vector(s_data);
+ when 16#99# =>
+ sbuf(s_ssel) <= s_data;
+ all_trans_o(s_ssel) <= '1';
+ when 16#9A# => ssel <= s_data;
+ when 16#A0# => p2 <= s_data;
+ when 16#A8# => ie <= conv_std_logic_vector(s_data,8);
+ when 16#B0# => p3 <= s_data;
+ when 16#B8# => ip <= conv_std_logic_vector(s_data,8);
+ when 16#D0# =>
+ psw(7 downto 1) <= conv_std_logic_vector(s_data(7 downto 1),7);
+ when 16#E0# => acc <= s_data;
+ when 16#F0# => b <= s_data;
+ when others => NULL;
+ end case;
+ -- write one byte to bitadressable GPR
+ elsif conv_std_logic_vector(s_adr(7 downto 4),4)="0010" then
+ gprbit(conv_integer(s_adr(3 downto 0))) <= s_data;
+ elsif conv_std_logic_vector(s_adr,8)="00000000" then
+ s_r0_b0 <= s_data; -- write R0 / Bank 0
+ elsif conv_std_logic_vector(s_adr,8)="00000001" then
+ s_r1_b0 <= s_data; -- write R1 / Bank 0
+ elsif conv_std_logic_vector(s_adr,8)="00001000" then
+ s_r0_b1 <= s_data; -- write R0 / Bank 1
+ elsif conv_std_logic_vector(s_adr,8)="00001001" then
+ s_r1_b1 <= s_data; -- write R1 / Bank 1
+ elsif conv_std_logic_vector(s_adr,8)="00010000" then
+ s_r0_b2 <= s_data; -- write R0 / Bank 2
+ elsif conv_std_logic_vector(s_adr,8)="00010001" then
+ s_r1_b2 <= s_data; -- write R1 / Bank 2
+ elsif conv_std_logic_vector(s_adr,8)="00011000" then
+ s_r0_b3 <= s_data; -- write R0 / Bank 3
+ elsif conv_std_logic_vector(s_adr,8)="00011001" then
+ s_r1_b3 <= s_data; -- write R1 / Bank 3
+ else -- write on general purpose RAM
+ NULL;
+ end if;
+ when "110" =>
+ if (s_intblock='0' and s_intpre='1' and state=FETCH) or s_intpre2='1' or
+ (s_command /= ANL_C_BIT and
+ s_command /= ANL_C_NBIT and
+ s_command /= MOV_C_BIT and
+ s_command /= ORL_C_BIT and
+ s_command /= ORL_C_NBIT) then
+ if s_adr(7)='1' then
+ case s_adr(6 downto 3) is -- write only one bit of an SFR
+ when "0000" =>
+ p0(conv_integer(s_adr(2 downto 0))) <= s_bdata;
+ when "0001" =>
+ tcon(s_tsel)(conv_integer(s_adr(2 downto 0))) <= s_bdata;
+ when "0010" =>
+ p1(conv_integer(s_adr(2 downto 0))) <= s_bdata;
+ when "0011" =>
+ scon(s_ssel)(conv_integer(s_adr(2 downto 0))) <= s_bdata;
+ when "0100" =>
+ p2(conv_integer(s_adr(2 downto 0))) <= s_bdata;
+ when "0101" =>
+ ie(conv_integer(s_adr(2 downto 0))) <= s_bdata;
+ when "0110" =>
+ p3(conv_integer(s_adr(2 downto 0))) <= s_bdata;
+ when "0111" =>
+ ip(conv_integer(s_adr(2 downto 0))) <= s_bdata;
+ when "1010" =>
+ case s_adr(2 downto 0) is
+ when "000" => NULL;
+ when "001" => psw(1) <= s_bdata;
+ when "010" => psw(2) <= s_bdata;
+ when "011" => psw(3) <= s_bdata;
+ when "100" => psw(4) <= s_bdata;
+ when "101" => psw(5) <= s_bdata;
+ when "110" => psw(6) <= s_bdata;
+ when "111" => psw(7) <= s_bdata;
+ when others => NULL;
+ end case;
+ when "1100" =>
+ acc(conv_integer(s_adr(2 downto 0))) <= s_bdata;
+ when "1110" =>
+ b(conv_integer(s_adr(2 downto 0))) <= s_bdata;
+ when others => NULL;
+ end case;
+ else -- write one bit to bitadressable GP
+ gprbit(conv_integer(s_adr(6 downto 3)))
+ (conv_integer(s_adr(2 downto 0))) <= s_bdata;
+ end if;
+ else
+ psw(7) <= s_bdata; -- write CY
+ end if;
+ when "111" =>
+ case s_command is
+ when DA_A | RLC_A | RRC_A => -- write ACC, CY
+ acc <= s_data;
+ psw(7) <= new_cy_i(1);
+ when DIV_AB | MUL_AB => -- write ACC, B, CY, OV
+ acc <= s_data;
+ b <= unsigned(aludatb_i);
+ psw(7) <= '0';
+ psw(2) <= new_ov_i;
+ when others => NULL;
+ end case;
+ when others => NULL;
+ end case;
+ end if;
+ end if;
+ end process p_write_ram;
+
+end rtl;
+
diff --git a/testsuite/synth/issue2273/control_mem_rtl_cfg.vhd b/testsuite/synth/issue2273/control_mem_rtl_cfg.vhd
new file mode 100644
index 000000000..f00fb8a20
--- /dev/null
+++ b/testsuite/synth/issue2273/control_mem_rtl_cfg.vhd
@@ -0,0 +1,71 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Helmut Mayrhofer
+--
+-- Filename: control_mem_rtl_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Describe all sequential funcitonality like read from
+-- special function registers, observe interrupt sources,
+-- write to special function registers, and read or write
+-- to the bit addressable memory area.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration control_mem_rtl_cfg of control_mem is
+ for rtl
+ end for;
+end control_mem_rtl_cfg; \ No newline at end of file
diff --git a/testsuite/synth/issue2273/dcml_adjust_.vhd b/testsuite/synth/issue2273/dcml_adjust_.vhd
new file mode 100644
index 000000000..8e86e7dff
--- /dev/null
+++ b/testsuite/synth/issue2273/dcml_adjust_.vhd
@@ -0,0 +1,89 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: dcml_adjust_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Combinational design to calculate the decimal
+-- representation (BCD) of a data bus.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+-----------------------------ENTITY DECLARATION--------------------------------
+
+entity dcml_adjust is
+
+ generic (DWIDTH : integer := 12);
+
+ port (data_i : in std_logic_vector(DWIDTH-1 downto 0);
+ cy_i : in std_logic_vector((DWIDTH-1)/4 downto 0);
+ data_o : out std_logic_vector(DWIDTH-1 downto 0);
+ cy_o : out std_logic);
+
+ -----------------------------------------------------------------------------
+ -- data_i .......... Data bus
+ -- cy_i ............ Carry flags (one for each nibble)
+ -- data_o .......... Adjusted data bus
+ -- cy_o ............ New overall carry flag
+ -----------------------------------------------------------------------------
+
+end dcml_adjust;
+
diff --git a/testsuite/synth/issue2273/dcml_adjust_rtl.vhd b/testsuite/synth/issue2273/dcml_adjust_rtl.vhd
new file mode 100644
index 000000000..fa27c30a0
--- /dev/null
+++ b/testsuite/synth/issue2273/dcml_adjust_rtl.vhd
@@ -0,0 +1,142 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: dcml_adjust_rtl.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Combinational design to calculate the decimal
+-- representation (BCD) of a data bus.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture rtl of dcml_adjust is
+
+begin -- rtl
+
+ p_calc_adjst: process (data_i, cy_i)
+
+ variable v_cy : std_logic_vector((DWIDTH-1)/4 downto 0);
+ variable v_nxtcy : std_logic;
+ variable v_tmpda : unsigned(DWIDTH downto 0);
+ variable v_tmpda1 : unsigned(4 downto 0);
+ variable v_compvl : unsigned(3 downto 0);
+
+ begin -- process p_calc_adjst
+ v_tmpda(DWIDTH-1 downto 0) := unsigned(data_i);
+ v_tmpda(DWIDTH) := '0';
+ v_cy := cy_i;
+ v_nxtcy := '0';
+ for i in 0 to (DWIDTH-1)/4 loop
+ if DWIDTH-i*4 <= 4 then
+ -- Calculate the decimal adjustment of the last nibble/rest of bits
+ v_compvl := conv_unsigned(0,4);
+ v_compvl(DWIDTH-1-i*4 downto 0) := v_tmpda(DWIDTH-1 downto i*4);
+ if (v_cy(i) = '1') or (v_compvl > conv_unsigned(9,4)) then
+ if DWIDTH-i*4 > 2 then
+ v_tmpda(DWIDTH downto i*4) := v_tmpda(DWIDTH-1 downto i*4) +
+ conv_unsigned(6,v_tmpda(DWIDTH downto i*4)'LENGTH);
+ else
+ v_tmpda(DWIDTH downto i*4) := v_tmpda(DWIDTH-1 downto i*4) +
+ conv_unsigned(2,v_tmpda(DWIDTH downto i*4)'LENGTH);
+ end if;
+ end if;
+ -- An already set intermediate carry flag must not be lost.
+ v_cy(i) := v_tmpda(DWIDTH) or v_cy(i);
+ else
+ -- Calculate the decimal adjustment of all nibbles, but the last one.
+ v_compvl := v_tmpda(i*4+3 downto i*4);
+ v_tmpda1 := conv_unsigned(0,5);
+ if (v_cy(i) = '1') or (v_compvl > conv_unsigned(9,4)) then
+ for j in i to (DWIDTH-1)/4 loop
+ if DWIDTH-1 > j*4+3 then
+ -- Calculate all subsequent nibbles from the actual position up
+ -- to the one before the last.
+ if j=i then
+ v_tmpda1 := v_tmpda(j*4+3 downto j*4) +
+ conv_unsigned(6,5);
+ v_nxtcy := v_tmpda1(4);
+ v_tmpda(j*4+3 downto j*4) := v_tmpda1(3 downto 0);
+ else
+ v_tmpda1 := v_tmpda(j*4+3 downto j*4) +
+ conv_unsigned(v_nxtcy,5);
+ v_nxtcy := v_tmpda1(4);
+ v_tmpda(j*4+3 downto j*4) := v_tmpda1(3 downto 0);
+ end if;
+ -- An already set intermediate carry flag must not be lost.
+ v_cy(j) := v_tmpda1(4) or v_cy(j);
+ else
+ -- Calculate the last nibble.
+ if j=i then
+ v_tmpda(DWIDTH downto j*4) := v_tmpda(DWIDTH-1 downto j*4) +
+ conv_unsigned(6,v_tmpda(DWIDTH downto j*4)'LENGTH);
+ else
+ v_tmpda(DWIDTH downto j*4) := v_tmpda(DWIDTH-1 downto j*4) +
+ conv_unsigned(v_nxtcy,v_tmpda(DWIDTH downto j*4)'LENGTH);
+ end if;
+ -- An already set intermediate carry flag must not be lost.
+ v_cy(j) := v_tmpda(DWIDTH) or v_cy(j);
+ end if;
+ end loop; -- j
+ end if;
+ end if;
+ end loop; -- i
+ -- Generate outputs
+ cy_o <= v_cy(v_cy'HIGH);
+ data_o <= std_logic_vector(v_tmpda(DWIDTH-1 downto 0));
+ end process p_calc_adjst;
+
+end rtl;
diff --git a/testsuite/synth/issue2273/dcml_adjust_rtl_cfg.vhd b/testsuite/synth/issue2273/dcml_adjust_rtl_cfg.vhd
new file mode 100644
index 000000000..593261e9a
--- /dev/null
+++ b/testsuite/synth/issue2273/dcml_adjust_rtl_cfg.vhd
@@ -0,0 +1,72 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: dcml_adjust_rtl_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Combinational design to calculate the decimal
+-- representation (BCD) of a data bus.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration dcml_adjust_rtl_cfg of dcml_adjust is
+
+ for rtl
+
+ end for;
+
+end dcml_adjust_rtl_cfg;
diff --git a/testsuite/synth/issue2273/mc8051.f b/testsuite/synth/issue2273/mc8051.f
new file mode 100644
index 000000000..394c9783c
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051.f
@@ -0,0 +1,45 @@
+mc8051_p.vhd
+control_fsm_.vhd
+control_fsm_rtl.vhd
+control_fsm_rtl_cfg.vhd
+control_mem_.vhd
+control_mem_rtl.vhd
+control_mem_rtl_cfg.vhd
+alumux_.vhd
+alumux_rtl.vhd
+alumux_rtl_cfg.vhd
+alucore_.vhd
+alucore_rtl.vhd
+alucore_rtl_cfg.vhd
+addsub_cy_.vhd
+addsub_cy_rtl.vhd
+addsub_cy_rtl_cfg.vhd
+addsub_ovcy_.vhd
+addsub_ovcy_rtl.vhd
+addsub_ovcy_rtl_cfg.vhd
+addsub_core_.vhd
+addsub_core_struc.vhd
+addsub_core_struc_cfg.vhd
+comb_divider_.vhd
+comb_divider_rtl.vhd
+comb_divider_rtl_cfg.vhd
+comb_mltplr_.vhd
+comb_mltplr_rtl.vhd
+comb_mltplr_rtl_cfg.vhd
+dcml_adjust_.vhd
+dcml_adjust_rtl.vhd
+dcml_adjust_rtl_cfg.vhd
+mc8051_siu_.vhd
+mc8051_siu_rtl.vhd
+mc8051_siu_rtl_cfg.vhd
+mc8051_tmrctr_.vhd
+mc8051_tmrctr_rtl.vhd
+mc8051_tmrctr_rtl_cfg.vhd
+mc8051_alu_.vhd
+mc8051_alu_struc.vhd
+mc8051_alu_struc_cfg.vhd
+mc8051_control_.vhd
+mc8051_control_struc.vhd
+mc8051_control_struc_cfg.vhd
+mc8051_core_.vhd
+mc8051_core_struc.vhd
diff --git a/testsuite/synth/issue2273/mc8051_alu_.vhd b/testsuite/synth/issue2273/mc8051_alu_.vhd
new file mode 100644
index 000000000..660dc0518
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_alu_.vhd
@@ -0,0 +1,103 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: mc8051_alu_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.7 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:44 $
+--
+--
+-- Description: Connects the units alumux, alucore, addsub_core,
+-- comb_mltplr, comb_divider, and dcml_adjust together.
+-- The whole design is made up of combinational logic.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+library work;
+use work.mc8051_p.all;
+
+-----------------------------ENTITY DECLARATION--------------------------------
+
+entity mc8051_alu is
+
+ generic (DWIDTH : integer := 8); -- Data width of the ALU
+
+ port (rom_data_i : in std_logic_vector(DWIDTH-1 downto 0);
+ ram_data_i : in std_logic_vector(DWIDTH-1 downto 0);
+ acc_i : in std_logic_vector(DWIDTH-1 downto 0);
+ cmd_i : in std_logic_vector(5 downto 0);
+ cy_i : in std_logic_vector((DWIDTH-1)/4 downto 0);
+ ov_i : in std_logic;
+
+ new_cy_o : out std_logic_vector((DWIDTH-1)/4 downto 0);
+ new_ov_o : out std_logic;
+ result_a_o : out std_logic_vector(DWIDTH-1 downto 0);
+ result_b_o : out std_logic_vector(DWIDTH-1 downto 0));
+
+end mc8051_alu;
+--Inputs:
+-- rom_data_i...... data input from ROM
+-- ram_data_i...... data input from RAM
+-- acc_i........... the contents of the accumulator register
+-- cmd_i........... command from the control unit
+-- cy_i............ CY-Flags of the SFR
+-- ov_i............ OV-Flag of the SFR
+--Outputs:
+-- new_cy_o........ new CY-Flags for SFR
+-- new_ov_o........ new OV-Flag for SFR
+-- result_a_o...... result
+-- result_b_o...... result
diff --git a/testsuite/synth/issue2273/mc8051_alu_struc.vhd b/testsuite/synth/issue2273/mc8051_alu_struc.vhd
new file mode 100644
index 000000000..25555dab6
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_alu_struc.vhd
@@ -0,0 +1,197 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: mc8051_alu_struc.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.9 $
+--
+-- Date of Latest Version: $Date: 2006-09-07 10:02:11 $
+--
+--
+-- Description: Connects the units alumux, alucore, addsub_core,
+-- comb_mltplr, comb_divider, and dcml_adjust together.
+-- The whole design is made up of combinational logic.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture struc of mc8051_alu is
+
+ signal s_alu_result : std_logic_vector(DWIDTH-1 downto 0);
+ signal s_alu_new_cy : std_logic_vector((DWIDTH-1)/4 downto 0);
+ signal s_alu_op_a : std_logic_vector(DWIDTH-1 downto 0);
+ signal s_alu_op_b : std_logic_vector(DWIDTH-1 downto 0);
+ signal s_alu_cmd : std_logic_vector(3 downto 0);
+ signal s_dvdnd : std_logic_vector(DWIDTH-1 downto 0);
+ signal s_dvsor : std_logic_vector(DWIDTH-1 downto 0);
+ signal s_qutnt : std_logic_vector(DWIDTH-1 downto 0);
+ signal s_rmndr : std_logic_vector(DWIDTH-1 downto 0);
+ signal s_mltplcnd : std_logic_vector(DWIDTH-1 downto 0);
+ signal s_mltplctr : std_logic_vector(DWIDTH-1 downto 0);
+ signal s_product : std_logic_vector((DWIDTH*2)-1 downto 0);
+ signal s_dcml_data : std_logic_vector(DWIDTH-1 downto 0);
+ signal s_dcml_rslt : std_logic_vector(DWIDTH-1 downto 0);
+ signal s_dcml_cy : std_logic;
+ signal s_addsub_rslt : std_logic_vector(DWIDTH-1 downto 0);
+ signal s_addsub_newcy : std_logic_vector((DWIDTH-1)/4 downto 0);
+ signal s_addsub_ov : std_logic;
+ signal s_addsub_cy : std_logic;
+ signal s_addsub : std_logic;
+ signal s_addsub_opa : std_logic_vector(DWIDTH-1 downto 0);
+ signal s_addsub_opb : std_logic_vector(DWIDTH-1 downto 0);
+
+begin -- architecture structural
+
+ i_alumux : alumux
+ generic map (
+ DWIDTH => DWIDTH)
+ port map (
+ -- Primary I/Os of the ALU unit.
+ rom_data_i => rom_data_i,
+ ram_data_i => ram_data_i,
+ acc_i => acc_i,
+ cmd_i => cmd_i,
+ cy_i => cy_i,
+ ov_i => ov_i,
+ cy_o => new_cy_o,
+ ov_o => new_ov_o,
+ result_a_o => result_a_o,
+ result_b_o => result_b_o,
+ -- I/Os connecting the submodules.
+ result_i => s_alu_result,
+ new_cy_i => s_alu_new_cy,
+ addsub_rslt_i => s_addsub_rslt,
+ addsub_cy_i => s_addsub_newcy,
+ addsub_ov_i => s_addsub_ov,
+ op_a_o => s_alu_op_a,
+ op_b_o => s_alu_op_b,
+ alu_cmd_o => s_alu_cmd,
+ opa_o => s_addsub_opa,
+ opb_o => s_addsub_opb,
+ addsub_o => s_addsub,
+ addsub_cy_o => s_addsub_cy,
+ dvdnd_o => s_dvdnd,
+ dvsor_o => s_dvsor,
+ qutnt_i => s_qutnt,
+ rmndr_i => s_rmndr,
+ mltplcnd_o => s_mltplcnd,
+ mltplctr_o => s_mltplctr,
+ product_i => s_product,
+ dcml_data_o => s_dcml_data,
+ dcml_data_i => s_dcml_rslt,
+ dcml_cy_i => s_dcml_cy);
+
+ i_alucore : alucore
+ generic map (
+ DWIDTH => DWIDTH)
+ port map (
+ op_a_i => s_alu_op_a,
+ op_b_i => s_alu_op_b,
+ alu_cmd_i => s_alu_cmd,
+ cy_i => cy_i,
+ cy_o => s_alu_new_cy,
+ result_o => s_alu_result);
+
+ i_addsub_core : addsub_core
+ generic map (DWIDTH => DWIDTH)
+ port map (opa_i => s_addsub_opa,
+ opb_i => s_addsub_opb,
+ addsub_i => s_addsub,
+ cy_i => s_addsub_cy,
+ cy_o => s_addsub_newcy,
+ ov_o => s_addsub_ov,
+ rslt_o => s_addsub_rslt);
+
+ gen_multiplier1 : if C_IMPL_MUL = 1 generate
+ i_comb_mltplr : comb_mltplr
+ generic map (
+ DWIDTH => DWIDTH)
+ port map (
+ mltplcnd_i => s_mltplcnd,
+ mltplctr_i => s_mltplctr,
+ product_o => s_product);
+ end generate gen_multiplier1;
+ gen_multiplier0 : if C_IMPL_MUL /= 1 generate
+ s_product <= (others => '0');
+ end generate gen_multiplier0;
+
+ gen_divider1 : if C_IMPL_DIV = 1 generate
+ i_comb_divider : comb_divider
+ generic map (
+ DWIDTH => DWIDTH)
+ port map (
+ dvdnd_i => s_dvdnd,
+ dvsor_i => s_dvsor,
+ qutnt_o => s_qutnt,
+ rmndr_o => s_rmndr);
+ end generate gen_divider1;
+ gen_divider0 : if C_IMPL_DIV /= 1 generate
+ s_qutnt <= (others => '0');
+ s_rmndr <= (others => '0');
+ end generate gen_divider0;
+
+ gen_dcml_adj1 : if C_IMPL_DA = 1 generate
+ i_dcml_adjust : dcml_adjust
+ generic map (
+ DWIDTH => DWIDTH)
+ port map (
+ data_i => s_dcml_data,
+ cy_i => cy_i,
+ data_o => s_dcml_rslt,
+ cy_o => s_dcml_cy);
+ end generate gen_dcml_adj1;
+ gen_dcml_adj0 : if C_IMPL_DA /= 1 generate
+ s_dcml_rslt <= (others => '0');
+ s_dcml_cy <= '0';
+ end generate gen_dcml_adj0;
+
+end struc;
diff --git a/testsuite/synth/issue2273/mc8051_alu_struc_cfg.vhd b/testsuite/synth/issue2273/mc8051_alu_struc_cfg.vhd
new file mode 100644
index 000000000..8866437d8
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_alu_struc_cfg.vhd
@@ -0,0 +1,96 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: mc8051_alu_struc_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.6 $
+--
+-- Date of Latest Version: $Date: 2006-09-07 10:02:31 $
+--
+--
+-- Description: Connects the units alumux, alucore, addsub_core,
+-- comb_mltplr, comb_divider, and dcml_adjust together.
+-- The whole design is made up of combinational logic.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration mc8051_alu_struc_cfg of mc8051_alu is
+
+ for struc
+ for i_alumux : alumux
+ use configuration work.alumux_rtl_cfg;
+ end for;
+ for i_alucore : alucore
+ use configuration work.alucore_rtl_cfg;
+ end for;
+ for i_addsub_core : addsub_core
+ use configuration work.addsub_core_struc_cfg;
+ end for;
+ for gen_multiplier1
+ for all : comb_mltplr
+ use configuration work.comb_mltplr_rtl_cfg;
+ end for;
+ end for;
+ for gen_divider1
+ for all : comb_divider
+ use configuration work.comb_divider_rtl_cfg;
+ end for;
+ end for;
+ for gen_dcml_adj1
+ for all : dcml_adjust
+ use configuration work.dcml_adjust_rtl_cfg;
+ end for;
+ end for;
+ end for;
+
+end mc8051_alu_struc_cfg;
diff --git a/testsuite/synth/issue2273/mc8051_control_.vhd b/testsuite/synth/issue2273/mc8051_control_.vhd
new file mode 100644
index 000000000..98060c783
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_control_.vhd
@@ -0,0 +1,144 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Helmut Mayrhofer
+--
+-- Filename: mc8051_control_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.7 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:45 $
+--
+--
+-- Description: Connects the units control_fsm and control_mem. This
+-- unit manages the whole microcontroller core.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+library work;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+use work.mc8051_p.all;
+
+
+------------------------ ENTITY DECLARATION -------------------------
+entity mc8051_control is
+
+ port (pc_o : out std_logic_vector(15 downto 0); -- Programmcounter =
+ -- ROM-adress
+ rom_data_i : in std_logic_vector(7 downto 0); -- data input from ROM
+ ram_data_o : out std_logic_vector(7 downto 0); -- data output to
+ -- internal RAM
+ ram_data_i : in std_logic_vector(7 downto 0); -- data input from
+ -- internal RAM
+ ram_adr_o : out std_logic_vector(6 downto 0); -- internal RAM-adress
+ reg_data_o : out std_logic_vector(7 downto 0); -- data for ALU
+ ram_wr_o : out std_logic; -- read (0) / write (1)
+ -- internal RAM
+ cy_o : out std_logic_vector(1 downto 0); -- Carry Flag
+ ov_o : out std_logic; -- Overflow Flag
+ ram_en_o : out std_logic; -- RAM-block enable
+ alu_cmd_o : out std_logic_vector (5 downto 0); -- ALU operationscode
+ aludata_i : in std_logic_vector (7 downto 0); -- ALU result
+ aludatb_i : in std_logic_vector (7 downto 0); -- 2nd ALU result
+ acc_o : out std_logic_vector (7 downto 0); -- ACC register
+ new_cy_i : in std_logic_vector(1 downto 0); -- CY result of ALU
+ new_ov_i : in std_logic; -- OV result of ALU
+ reset : in std_logic; -- reset signal
+ clk : in std_logic; -- clock signal
+ cen : in std_logic; -- clock enable signal
+ int0_i : in std_logic_vector(C_IMPL_N_EXT-1 downto 0); -- ext.Int
+ int1_i : in std_logic_vector(C_IMPL_N_EXT-1 downto 0); -- ext.Int
+
+ datax_i : in std_logic_vector (7 downto 0); -- ext. RAM
+ datax_o : out std_logic_vector (7 downto 0); -- ext. RAM
+ adrx_o : out std_logic_vector (15 downto 0); -- ext. RAM
+ wrx_o : out std_logic; -- ext. RAM
+ memx_o : out std_logic; -- ext. RAM
+
+ p0_i : in std_logic_vector(7 downto 0); -- IO-port0
+ p1_i : in std_logic_vector(7 downto 0); -- IO-port1
+ p2_i : in std_logic_vector(7 downto 0); -- IO-port2
+ p3_i : in std_logic_vector(7 downto 0); -- IO-port3
+
+ p0_o : out std_logic_vector(7 downto 0); -- IO-port0
+ p1_o : out std_logic_vector(7 downto 0); -- IO-port1
+ p2_o : out std_logic_vector(7 downto 0); -- IO-port2
+ p3_o : out std_logic_vector(7 downto 0); -- IO-port3
+
+ -- Signals to and from the SIUs
+
+ all_trans_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ all_scon_o : out std_logic_vector(6*C_IMPL_N_SIU-1 downto 0);
+ all_sbuf_o : out std_logic_vector(8*C_IMPL_N_SIU-1 downto 0);
+ all_smod_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ all_scon_i : in std_logic_vector(3*C_IMPL_N_SIU-1 downto 0);
+ all_sbuf_i : in std_logic_vector(8*C_IMPL_N_SIU-1 downto 0);
+
+ -- signals to and from the timer/counters
+
+ all_tcon_tr0_o : out std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_tcon_tr1_o : out std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_tmod_o : out std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_reload_o : out std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_wt_o : out std_logic_vector(2*C_IMPL_N_TMR-1 downto 0);
+ all_wt_en_o : out std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+
+ all_tf0_i : in std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_tf1_i : in std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_tl0_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_tl1_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_th0_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_th1_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0));
+
+end mc8051_control;
+
diff --git a/testsuite/synth/issue2273/mc8051_control_struc.vhd b/testsuite/synth/issue2273/mc8051_control_struc.vhd
new file mode 100644
index 000000000..16c3f57c6
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_control_struc.vhd
@@ -0,0 +1,269 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Helmut Mayrhofer
+--
+-- Filename: mc8051_control_struc.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.7 $
+--
+-- Date of Latest Version: $Date: 2006-09-07 10:03:45 $
+--
+--
+-- Description: Connects the units control_fsm and control_mem. This
+-- unit manages the whole microcontroller core.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture struc of mc8051_control is
+
+ -- signals connecting the fsm and the mem unit
+
+ signal s_pc_inc_en : std_logic_vector (3 downto 0);
+ signal s_regs_wr_en : std_logic_vector (2 downto 0);
+ signal s_data_mux : std_logic_vector (3 downto 0);
+ signal s_bdata_mux : std_logic_vector (3 downto 0);
+ signal s_adr_mux : std_logic_vector (3 downto 0);
+ signal s_adrx_mux : std_logic_vector (1 downto 0);
+ signal s_wrx_mux : std_logic;
+ signal s_help_en : std_logic_vector (3 downto 0);
+ signal s_help16_en : std_logic_vector (1 downto 0);
+ signal s_helpb_en : std_logic;
+ signal s_intpre2_d : std_logic;
+ signal s_intpre2_en : std_logic;
+ signal s_intlow_d : std_logic;
+ signal s_intlow_en : std_logic;
+ signal s_inthigh_d : std_logic;
+ signal s_inthigh_en : std_logic;
+ signal s_nextstate : t_state; -- enable signal for state
+ signal state : t_state; -- actual state
+ signal s_command : std_logic_vector (7 downto 0);
+ signal s_help : std_logic_vector(7 downto 0); -- general help-register
+ signal s_bit_data : std_logic;
+ signal s_intpre : std_logic; -- an interrupt must start
+ signal s_intpre2 : std_logic; -- prepare for interrupt
+ signal s_inthigh : std_logic; -- high priority int is running
+ signal s_intlow : std_logic; -- low priority int is running
+ signal s_intblock : std_logic; -- interrupt delay at RETI, IE, IP
+ signal s_ri : std_logic;
+ signal s_ti : std_logic;
+ signal s_tf1 : std_logic;
+ signal s_tf0 : std_logic;
+ signal s_ie1 : std_logic;
+ signal s_ie0 : std_logic;
+ signal ie : std_logic_vector(7 downto 0);
+ signal ip : std_logic_vector(7 downto 0);
+ signal psw : std_logic_vector(7 downto 0);
+ signal acc : std_logic_vector(7 downto 0);
+ signal s_ext0isr_d : std_logic;
+ signal s_ext1isr_d : std_logic;
+ signal s_ext0isrh_d : std_logic;
+ signal s_ext1isrh_d : std_logic;
+ signal s_ext0isr_en : std_logic;
+ signal s_ext1isr_en : std_logic;
+ signal s_ext0isrh_en : std_logic;
+ signal s_ext1isrh_en : std_logic;
+
+
+
+begin -- architecture structural
+
+ acc_o <= acc;
+
+ i_control_fsm : control_fsm
+ port map(state_i => state,
+ help_i => s_help,
+ bit_data_i => s_bit_data,
+ aludata_i => aludata_i,
+ command_i => s_command,
+ inthigh_i => s_inthigh,
+ intlow_i => s_intlow,
+ intpre_i => s_intpre,
+ intpre2_i => s_intpre2,
+ intblock_i => s_intblock,
+ ti_i => s_ti,
+ ri_i => s_ri,
+ ie0_i => s_ie0,
+ ie1_i => s_ie1,
+ tf0_i => s_tf0,
+ tf1_i => s_tf1,
+ acc => acc,
+ psw => psw,
+ ie => ie,
+ ip => ip,
+
+ alu_cmd_o => alu_cmd_o,
+ pc_inc_en_o => s_pc_inc_en,
+ nextstate_o => s_nextstate,
+ adr_mux_o => s_adr_mux,
+ adrx_mux_o => s_adrx_mux,
+ wrx_mux_o => s_wrx_mux,
+ data_mux_o => s_data_mux,
+ bdata_mux_o => s_bdata_mux,
+ regs_wr_en_o => s_regs_wr_en,
+ help_en_o => s_help_en,
+ help16_en_o => s_help16_en,
+ helpb_en_o => s_helpb_en,
+ inthigh_en_o => s_inthigh_en,
+ intlow_en_o => s_intlow_en,
+ intpre2_en_o => s_intpre2_en,
+ inthigh_d_o => s_inthigh_d,
+ intlow_d_o => s_intlow_d,
+ intpre2_d_o => s_intpre2_d,
+ ext0isr_d_o => s_ext0isr_d ,
+ ext1isr_d_o => s_ext1isr_d ,
+ ext0isrh_d_o => s_ext0isrh_d ,
+ ext1isrh_d_o => s_ext1isrh_d ,
+ ext0isr_en_o => s_ext0isr_en ,
+ ext1isr_en_o => s_ext1isr_en ,
+ ext0isrh_en_o => s_ext0isrh_en,
+ ext1isrh_en_o => s_ext1isrh_en);
+
+
+ i_control_mem : control_mem
+ port map(pc_o => pc_o,
+ rom_data_i => rom_data_i,
+ ram_data_o => ram_data_o,
+ ram_data_i => ram_data_i,
+ ram_adr_o => ram_adr_o,
+ reg_data_o => reg_data_o,
+ ram_wr_o => ram_wr_o,
+ cy_o => cy_o,
+ ov_o => ov_o,
+ ram_en_o => ram_en_o,
+ aludata_i => aludata_i,
+ aludatb_i => aludatb_i,
+ acc_o => acc,
+ new_cy_i => new_cy_i,
+ new_ov_i => new_ov_i,
+ reset => reset,
+ clk => clk,
+ cen => cen,
+ int0_i => int0_i,
+ int1_i => int1_i,
+ p0_i => p0_i,
+ p1_i => p1_i,
+ p2_i => p2_i,
+ p3_i => p3_i,
+ p0_o => p0_o,
+ p1_o => p1_o,
+ p2_o => p2_o,
+ p3_o => p3_o,
+ all_trans_o => all_trans_o,
+ all_scon_o => all_scon_o,
+ all_sbuf_o => all_sbuf_o,
+ all_smod_o => all_smod_o,
+ all_scon_i => all_scon_i,
+ all_sbuf_i => all_sbuf_i,
+ all_tcon_tr0_o => all_tcon_tr0_o,
+ all_tcon_tr1_o => all_tcon_tr1_o,
+ all_tmod_o => all_tmod_o,
+ all_reload_o => all_reload_o,
+ all_wt_o => all_wt_o,
+ all_wt_en_o => all_wt_en_o,
+ all_tf0_i => all_tf0_i,
+ all_tf1_i => all_tf1_i,
+ all_tl0_i => all_tl0_i,
+ all_tl1_i => all_tl1_i,
+ all_th0_i => all_th0_i,
+ all_th1_i => all_th1_i,
+
+ state_o => state,
+ help_o => s_help,
+ bit_data_o => s_bit_data,
+ command_o => s_command,
+ inthigh_o => s_inthigh,
+ intlow_o => s_intlow,
+ intpre_o => s_intpre,
+ intpre2_o => s_intpre2,
+ intblock_o => s_intblock,
+ ti_o => s_ti,
+ ri_o => s_ri,
+ ie0_o => s_ie0,
+ ie1_o => s_ie1,
+ tf0_o => s_tf0,
+ tf1_o => s_tf1,
+ psw_o => psw,
+ ie_o => ie,
+ ip_o => ip,
+ adrx_o => adrx_o,
+ datax_o => datax_o,
+ wrx_o => wrx_o,
+ memx_o => memx_o,
+
+ datax_i => datax_i,
+ pc_inc_en_i => s_pc_inc_en,
+ nextstate_i => s_nextstate,
+ adr_mux_i => s_adr_mux,
+ adrx_mux_i => s_adrx_mux,
+ wrx_mux_i => s_wrx_mux,
+ data_mux_i => s_data_mux,
+ bdata_mux_i => s_bdata_mux,
+ regs_wr_en_i => s_regs_wr_en,
+ help_en_i => s_help_en,
+ help16_en_i => s_help16_en,
+ helpb_en_i => s_helpb_en,
+ inthigh_en_i => s_inthigh_en,
+ intlow_en_i => s_intlow_en,
+ intpre2_en_i => s_intpre2_en,
+ inthigh_d_i => s_inthigh_d,
+ intlow_d_i => s_intlow_d,
+ intpre2_d_i => s_intpre2_d,
+ ext0isr_d_i => s_ext0isr_d ,
+ ext1isr_d_i => s_ext1isr_d ,
+ ext0isrh_d_i => s_ext0isrh_d ,
+ ext1isrh_d_i => s_ext1isrh_d ,
+ ext0isr_en_i => s_ext0isr_en ,
+ ext1isr_en_i => s_ext1isr_en ,
+ ext0isrh_en_i => s_ext0isrh_en,
+ ext1isrh_en_i => s_ext1isrh_en);
+
+end struc;
diff --git a/testsuite/synth/issue2273/mc8051_control_struc_cfg.vhd b/testsuite/synth/issue2273/mc8051_control_struc_cfg.vhd
new file mode 100644
index 000000000..b46fe7482
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_control_struc_cfg.vhd
@@ -0,0 +1,75 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Helmut Mayrhofer
+--
+-- Filename: mc8051_control_struc_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:45 $
+--
+--
+-- Description: Connects the units control_fsm and control_mem. This
+-- unit manages the whole microcontroller core.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration mc8051_control_struc_cfg of mc8051_control is
+ for struc
+ for i_control_fsm : control_fsm
+ use configuration work.control_fsm_rtl_cfg;
+ end for;
+ for i_control_mem : control_mem
+ use configuration work.control_mem_rtl_cfg;
+ end for;
+ end for;
+end mc8051_control_struc_cfg;
diff --git a/testsuite/synth/issue2273/mc8051_core_.vhd b/testsuite/synth/issue2273/mc8051_core_.vhd
new file mode 100644
index 000000000..32b92c9af
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_core_.vhd
@@ -0,0 +1,122 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Helmut Mayrhofer
+--
+-- Filename: mc8051_core_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.8 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:45 $
+--
+--
+-- Description: Connect the mc8051_control and mc8051_alu modules.
+-- Generate and connect a certain number of mc8051_tmrctr
+-- and mc8051_siu units.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+library work;
+use work.mc8051_p.all;
+
+-----------------------------ENTITY DECLARATION--------------------------------
+
+entity mc8051_core is
+
+ port (clk : in std_logic; -- system clock
+ cen : in std_logic; -- system clock enable
+ reset : in std_logic; -- system reset
+ rom_data_i : in std_logic_vector(7 downto 0); -- data input from ROM
+ ram_data_i : in std_logic_vector(7 downto 0); -- data input from
+ -- internal RAM
+ int0_i : in std_logic_vector(C_IMPL_N_EXT-1 downto 0); -- ext.Int
+ int1_i : in std_logic_vector(C_IMPL_N_EXT-1 downto 0); -- ext.Int
+ -- counter input 0 for T/C
+ all_t0_i : in std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ -- counter input 1 for T/C
+ all_t1_i : in std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ -- serial input for SIU
+ all_rxd_i : in std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ p0_i : in std_logic_vector(7 downto 0); -- IO-port0 input
+ p1_i : in std_logic_vector(7 downto 0); -- IO-port1 input
+ p2_i : in std_logic_vector(7 downto 0); -- IO-port2 input
+ p3_i : in std_logic_vector(7 downto 0); -- IO-port3 input
+
+ p0_o : out std_logic_vector(7 downto 0); -- IO-port0 output
+ p1_o : out std_logic_vector(7 downto 0); -- IO-port1 output
+ p2_o : out std_logic_vector(7 downto 0); -- IO-port2 output
+ p3_o : out std_logic_vector(7 downto 0); -- IO-port3 output
+ -- M0 serial output for SIU
+ all_rxd_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ -- serial output for SIU
+ all_txd_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ -- rxd direction signal
+ all_rxdwr_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+
+ rom_adr_o : out std_logic_vector(15 downto 0); -- Programmcounter =
+ -- ROM-adress
+ ram_data_o : out std_logic_vector(7 downto 0); -- data output to
+ -- internal RAM
+ ram_adr_o : out std_logic_vector(6 downto 0); -- internal RAM-address
+ ram_wr_o : out std_logic; -- read (0) / write (1)
+ ram_en_o : out std_logic; -- RAM-block enable
+
+ datax_i : in std_logic_vector (7 downto 0); -- ext. RAM data input
+ datax_o : out std_logic_vector (7 downto 0); -- ext. RAM data output
+ adrx_o : out std_logic_vector (15 downto 0); -- ext. RAM address
+ memx_o : out std_logic; -- ext. RAM access
+ wrx_o : out std_logic); -- ext. RAM write enable
+
+end mc8051_core;
+
diff --git a/testsuite/synth/issue2273/mc8051_core_struc.vhd b/testsuite/synth/issue2273/mc8051_core_struc.vhd
new file mode 100644
index 000000000..47bb3ec7c
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_core_struc.vhd
@@ -0,0 +1,224 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Helmut Mayrhofer
+--
+-- Filename: mc8051_core_struc.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.9 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:45 $
+--
+--
+-- Description: Connect the mc8051_control and mc8051_alu modules.
+-- Generate and connect a certain number of mc8051_tmrctr
+-- and mc8051_siu units.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture struc of mc8051_core is
+
+ -- signals connecting the control unit with the rest
+
+ signal s_reg_data: std_logic_vector(7 downto 0); -- data for ALU
+ signal s_cy : std_logic_vector(1 downto 0); -- Carry Flag
+ signal s_ov : std_logic; -- Overflow Flag
+ signal s_alu_cmd: std_logic_vector (5 downto 0); -- ALU operationscode
+ signal s_alu_data0: std_logic_vector (7 downto 0); -- ALU result
+ signal s_alu_data1: std_logic_vector (7 downto 0); -- 2nd ALU result
+ signal s_acc: std_logic_vector (7 downto 0); -- ACC register
+ signal s_cyb: std_logic_vector (1 downto 0); -- CY result of ALU
+ signal s_ovb: std_logic; -- OV result of ALU
+ signal s_reset: std_logic; -- reset signal
+ signal s_clk: std_logic; -- clock signal
+
+ -- signals to and from the SIUs
+
+ signal s_all_trans : std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ signal s_all_scon : std_logic_vector(6*C_IMPL_N_SIU-1 downto 0);
+ signal s_all_sbuf : std_logic_vector(8*C_IMPL_N_SIU-1 downto 0);
+ signal s_all_smod : std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ signal s_all_scon_out : std_logic_vector(3*C_IMPL_N_SIU-1 downto 0);
+ signal s_all_sbuf_out : std_logic_vector(8*C_IMPL_N_SIU-1 downto 0);
+
+ -- signals to and from the timer/counters
+
+ signal s_all_tcon_tr0 : std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ signal s_all_tcon_tr1 : std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ signal s_all_tmod : std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ signal s_all_reload : std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ signal s_all_wt : std_logic_vector(2*C_IMPL_N_TMR-1 downto 0);
+ signal s_all_wt_en : std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ signal s_all_tf0 : std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ signal s_all_tf1 : std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ signal s_all_tl0 : std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ signal s_all_th0 : std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ signal s_all_tl1 : std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ signal s_all_th1 : std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+
+begin -- architecture structural
+
+ i_mc8051_control : mc8051_control
+ port map(pc_o => rom_adr_o,
+ rom_data_i => rom_data_i,
+ ram_data_o => ram_data_o,
+ ram_data_i => ram_data_i,
+ ram_adr_o => ram_adr_o,
+ reg_data_o => s_reg_data,
+ ram_wr_o => ram_wr_o,
+ cy_o => s_cy,
+ ov_o => s_ov,
+ ram_en_o => ram_en_o,
+ alu_cmd_o => s_alu_cmd,
+ aludata_i => s_alu_data0,
+ aludatb_i => s_alu_data1,
+ acc_o => s_acc,
+ new_cy_i => s_cyb,
+ new_ov_i => s_ovb,
+ reset => reset,
+ clk => clk,
+ cen => cen,
+ int0_i => int0_i,
+ int1_i => int1_i,
+ p0_i => p0_i,
+ p1_i => p1_i,
+ p2_i => p2_i,
+ p3_i => p3_i,
+ p0_o => p0_o,
+ p1_o => p1_o,
+ p2_o => p2_o,
+ p3_o => p3_o,
+ all_trans_o => s_all_trans,
+ all_scon_o => s_all_scon,
+ all_sbuf_o => s_all_sbuf,
+ all_smod_o => s_all_smod,
+ all_scon_i => s_all_scon_out,
+ all_sbuf_i => s_all_sbuf_out,
+ all_tcon_tr0_o => s_all_tcon_tr0,
+ all_tcon_tr1_o => s_all_tcon_tr1,
+ all_tmod_o => s_all_tmod,
+ all_reload_o => s_all_reload,
+ all_wt_o => s_all_wt,
+ all_wt_en_o => s_all_wt_en,
+ all_tf0_i => s_all_tf0,
+ all_tf1_i => s_all_tf1,
+ all_tl0_i => s_all_tl0,
+ all_tl1_i => s_all_tl1,
+ all_th0_i => s_all_th0,
+ all_th1_i => s_all_th1,
+ adrx_o => adrx_o,
+ datax_o => datax_o,
+ wrx_o => wrx_o,
+ memx_o => memx_o,
+ datax_i => datax_i);
+
+
+ i_mc8051_alu : mc8051_alu
+ generic map (DWIDTH => 8)
+ port map(rom_data_i => rom_data_i, -- inputs to mc8051_alu
+ ram_data_i => s_reg_data,
+ acc_i => s_acc,
+ cmd_i => s_alu_cmd,
+ cy_i => s_cy,
+ ov_i => s_ov,
+
+ result_a_o => s_alu_data0, -- outputs of mc8051_alu
+ result_b_o => s_alu_data1,
+ new_cy_o => s_cyb,
+ new_ov_o => s_ovb);
+
+
+ gen_mc8051_siu : for i in c_impl_n_siu-1 downto 0 generate
+ i_mc8051_siu : mc8051_siu
+ port map (clk => clk, -- SIUs inputs
+ cen => cen,
+ reset => reset,
+ tf_i => s_all_tf1(i),
+ trans_i => s_all_trans(i),
+ rxd_i => all_rxd_i(i),
+ scon_i => s_all_scon((6*i)+5 downto i*6),
+ sbuf_i => s_all_sbuf((8*i)+7 downto i*8),
+ smod_i => s_all_smod(i),
+ -- SIUs outputs
+ sbuf_o => s_all_sbuf_out((8*i)+7 downto i*8),
+ scon_o => s_all_scon_out((3*i)+2 downto i*3),
+ rxdwr_o => all_rxdwr_o(i),
+ rxd_o => all_rxd_o(i),
+ txd_o => all_txd_o(i));
+ end generate;
+
+
+ gen_mc8051_tmrctr : for i in c_impl_n_tmr-1 downto 0 generate
+ i_mc8051_tmrctr : mc8051_tmrctr
+ port map (clk => clk, -- tmr_ctr inputs
+ cen => cen,
+ reset => reset,
+ int0_i => int0_i(i),
+ int1_i => int1_i(i),
+ t0_i => all_t0_i(i),
+ t1_i => all_t1_i(i),
+ tmod_i => s_all_tmod((8*i)+7 downto i*8),
+ tcon_tr0_i => s_all_tcon_tr0(i),
+ tcon_tr1_i => s_all_tcon_tr1(i),
+ reload_i => s_all_reload((8*i)+7 downto i*8),
+ wt_en_i => s_all_wt_en(i),
+ wt_i => s_all_wt((2*i)+1 downto i*2),
+ -- tmr_ctr outputs
+ th0_o => s_all_th0((8*i)+7 downto i*8),
+ tl0_o => s_all_tl0((8*i)+7 downto i*8),
+ th1_o => s_all_th1((8*i)+7 downto i*8),
+ tl1_o => s_all_tl1((8*i)+7 downto i*8),
+ tf0_o => s_all_tf0(i),
+ tf1_o => s_all_tf1(i));
+ end generate;
+
+
+end struc;
diff --git a/testsuite/synth/issue2273/mc8051_core_struc_cfg.vhd b/testsuite/synth/issue2273/mc8051_core_struc_cfg.vhd
new file mode 100644
index 000000000..6d528fabb
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_core_struc_cfg.vhd
@@ -0,0 +1,86 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Helmut Mayrhofer
+--
+-- Filename: mc8051_core_struc_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.6 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:45 $
+--
+--
+-- Description: Connect the mc8051_control and mc8051_alu modules.
+-- Generate and connect a certain number of mc8051_tmrctr
+-- and mc8051_siu units.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration mc8051_core_struc_cfg of mc8051_core is
+ for struc
+ for i_mc8051_control : mc8051_control
+ use configuration work.mc8051_control_struc_cfg;
+ end for;
+ for i_mc8051_alu : mc8051_alu
+ use configuration work.mc8051_alu_struc_cfg;
+ end for;
+ for gen_mc8051_siu
+ for all : mc8051_siu
+ use configuration work.mc8051_siu_rtl_cfg;
+ end for;
+ end for;
+ for gen_mc8051_tmrctr
+ for all : mc8051_tmrctr
+ use configuration work.mc8051_tmrctr_rtl_cfg;
+ end for;
+ end for;
+ end for;
+end mc8051_core_struc_cfg;
diff --git a/testsuite/synth/issue2273/mc8051_p.vhd b/testsuite/synth/issue2273/mc8051_p.vhd
new file mode 100644
index 000000000..5739de814
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_p.vhd
@@ -0,0 +1,864 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: mc8051_p.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.16 $
+--
+-- Date of Latest Version: $Date: 2006-09-07 10:29:29 $
+--
+--
+-- Description: Collection of constants, types, and components.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+package mc8051_p is
+
+ -----------------------------------------------------------------------------
+ -- Set data width of mc8051_alu (no other than 8 supported at the moment!)
+ -- Default: 8
+ constant C_DWIDTH : integer := 8;
+ -----------------------------------------------------------------------------
+
+ -----------------------------------------------------------------------------
+ -- Select whether to implement (1) or skip (0) the multiplier
+ -- Default: 1
+ constant C_IMPL_MUL : integer := 1;
+ -----------------------------------------------------------------------------
+
+ -----------------------------------------------------------------------------
+ -- Select whether to implement (1) or skip (0) the divider
+ -- Default: 1
+ constant C_IMPL_DIV : integer := 1;
+ -----------------------------------------------------------------------------
+
+ -----------------------------------------------------------------------------
+ -- Select whether to implement (1) or skip (0) the decimal adjustment command
+ -- Default: 1
+ constant C_IMPL_DA : integer := 1;
+ -----------------------------------------------------------------------------
+
+ -----------------------------------------------------------------------------
+ -- Select how many timer/counter units should be implemented
+ -- Default: 1
+ constant C_IMPL_N_TMR : integer := 1;
+ -----------------------------------------------------------------------------
+
+ -----------------------------------------------------------------------------
+ -- Select how many serial interface units should be implemented
+ -- Default: C_IMPL_N_TMR ---(DO NOT CHANGE!)---
+ constant C_IMPL_N_SIU : integer := C_IMPL_N_TMR;
+ -----------------------------------------------------------------------------
+
+ -----------------------------------------------------------------------------
+ -- Select how many external interrupt-inputs should be implemented
+ -- Default: C_IMPL_N_TMR ---(DO NOT CHANGE!)---
+ constant C_IMPL_N_EXT : integer := C_IMPL_N_TMR;
+ -----------------------------------------------------------------------------
+
+ constant OFF : std_logic_vector(5 downto 0) := "000000";
+ constant DA : std_logic_vector(5 downto 0) := "100000";
+ constant ADD_ACC_RAM : std_logic_vector(5 downto 0) := "100001";
+ constant ADD_ACC_ROM : std_logic_vector(5 downto 0) := "100010";
+ constant ADDC_ACC_RAM : std_logic_vector(5 downto 0) := "100011";
+ constant ADDC_ACC_ROM : std_logic_vector(5 downto 0) := "100100";
+ constant AND_ACC_RAM : std_logic_vector(5 downto 0) := "100101";
+ constant AND_ACC_ROM : std_logic_vector(5 downto 0) := "100110";
+ constant AND_RAM_ROM : std_logic_vector(5 downto 0) := "100111";
+ constant SUB_ACC_RAM : std_logic_vector(5 downto 0) := "101000";
+ constant SUB_ACC_ROM : std_logic_vector(5 downto 0) := "101001";
+ constant MUL_ACC_RAM : std_logic_vector(5 downto 0) := "101010";
+ constant DIV_ACC_RAM : std_logic_vector(5 downto 0) := "101011";
+ constant OR_RAM_ACC : std_logic_vector(5 downto 0) := "101100";
+ constant OR_ROM_ACC : std_logic_vector(5 downto 0) := "101101";
+ constant OR_ROM_RAM : std_logic_vector(5 downto 0) := "101110";
+ constant XOR_RAM_ACC : std_logic_vector(5 downto 0) := "101111";
+ constant XOR_ROM_ACC : std_logic_vector(5 downto 0) := "110000";
+ constant XOR_ROM_RAM : std_logic_vector(5 downto 0) := "110001";
+ constant RL_ACC : std_logic_vector(5 downto 0) := "110010";
+ constant RLC_ACC : std_logic_vector(5 downto 0) := "110011";
+ constant RR_ACC : std_logic_vector(5 downto 0) := "110100";
+ constant RRC_ACC : std_logic_vector(5 downto 0) := "110101";
+ constant INV_ACC : std_logic_vector(5 downto 0) := "110110";
+ constant INV_RAM : std_logic_vector(5 downto 0) := "110111";
+ constant DEC_ACC : std_logic_vector(5 downto 0) := "111000";
+ constant DEC_RAM : std_logic_vector(5 downto 0) := "111001";
+ constant COMP_RAM_ACC : std_logic_vector(5 downto 0) := "111010";
+ constant COMP_ROM_ACC : std_logic_vector(5 downto 0) := "111011";
+ constant COMP_ROM_RAM : std_logic_vector(5 downto 0) := "111100";
+ constant INC_ACC : std_logic_vector(5 downto 0) := "111110";
+ constant INC_RAM : std_logic_vector(5 downto 0) := "111111";
+
+ constant ACALL : std_logic_vector(4 downto 0) := "10001";
+ constant ADD_A_RR : std_logic_vector(4 downto 0) := "00101";
+ constant ADD_A_D : std_logic_vector(7 downto 0) := "00100101";
+ constant ADD_A_ATRI : std_logic_vector(6 downto 0) := "0010011";
+ constant ADD_A_DATA : std_logic_vector(7 downto 0) := "00100100";
+ constant ADDC_A_RR : std_logic_vector(4 downto 0) := "00111";
+ constant ADDC_A_D : std_logic_vector(7 downto 0) := "00110101";
+ constant ADDC_A_ATRI : std_logic_vector(6 downto 0) := "0011011";
+ constant ADDC_A_DATA : std_logic_vector(7 downto 0) := "00110100";
+ constant AJMP : std_logic_vector(4 downto 0) := "00001";
+ constant ANL_A_RR : std_logic_vector(4 downto 0) := "01011";
+ constant ANL_A_D : std_logic_vector(7 downto 0) := "01010101";
+ constant ANL_A_ATRI : std_logic_vector(6 downto 0) := "0101011";
+ constant ANL_A_DATA : std_logic_vector(7 downto 0) := "01010100";
+ constant ANL_D_A : std_logic_vector(7 downto 0) := "01010010";
+ constant ANL_D_DATA : std_logic_vector(7 downto 0) := "01010011";
+ constant ANL_C_BIT : std_logic_vector(7 downto 0) := "10000010";
+ constant ANL_C_NBIT : std_logic_vector(7 downto 0) := "10110000";
+ constant CJNE_A_D : std_logic_vector(7 downto 0) := "10110101";
+ constant CJNE_A_DATA : std_logic_vector(7 downto 0) := "10110100";
+ constant CJNE_RR_DATA : std_logic_vector(4 downto 0) := "10111";
+ constant CJNE_ATRI_DATA: std_logic_vector(6 downto 0) := "1011011" ;
+ constant CLR_A : std_logic_vector(7 downto 0) := "11100100";
+ constant CLR_C : std_logic_vector(7 downto 0) := "11000011";
+ constant CLR_BIT : std_logic_vector(7 downto 0) := "11000010";
+ constant CPL_A : std_logic_vector(7 downto 0) := "11110100";
+ constant CPL_C : std_logic_vector(7 downto 0) := "10110011";
+ constant CPL_BIT : std_logic_vector(7 downto 0) := "10110010";
+ constant DA_A : std_logic_vector(7 downto 0) := "11010100";
+ constant DEC_A : std_logic_vector(7 downto 0) := "00010100";
+ constant DEC_RR : std_logic_vector(4 downto 0) := "00011";
+ constant DEC_D : std_logic_vector(7 downto 0) := "00010101";
+ constant DEC_ATRI : std_logic_vector(6 downto 0) := "0001011";
+ constant DIV_AB : std_logic_vector(7 downto 0) := "10000100";
+ constant DJNZ_RR : std_logic_vector(4 downto 0) := "11011";
+ constant DJNZ_D : std_logic_vector(7 downto 0) := "11010101";
+ constant INC_A : std_logic_vector(7 downto 0) := "00000100";
+ constant INC_RR : std_logic_vector(4 downto 0) := "00001";
+ constant INC_D : std_logic_vector(7 downto 0) := "00000101";
+ constant INC_ATRI : std_logic_vector(6 downto 0) := "0000011";
+ constant INC_DPTR : std_logic_vector(7 downto 0) := "10100011";
+ constant JB : std_logic_vector(7 downto 0) := "00100000";
+ constant JBC : std_logic_vector(7 downto 0) := "00010000";
+ constant JC : std_logic_vector(7 downto 0) := "01000000";
+ constant JMP_A_DPTR : std_logic_vector(7 downto 0) := "01110011";
+ constant JNB : std_logic_vector(7 downto 0) := "00110000";
+ constant JNC : std_logic_vector(7 downto 0) := "01010000";
+ constant JNZ : std_logic_vector(7 downto 0) := "01110000";
+ constant JZ : std_logic_vector(7 downto 0) := "01100000";
+ constant LCALL : std_logic_vector(7 downto 0) := "00010010";
+ constant LJMP : std_logic_vector(7 downto 0) := "00000010";
+ constant MOV_A_RR : std_logic_vector(4 downto 0) := "11101";
+ constant MOV_A_D : std_logic_vector(7 downto 0) := "11100101";
+ constant MOV_A_ATRI : std_logic_vector(6 downto 0) := "1110011";
+ constant MOV_A_DATA : std_logic_vector(7 downto 0) := "01110100";
+ constant MOV_RR_A : std_logic_vector(4 downto 0) := "11111";
+ constant MOV_RR_D : std_logic_vector(4 downto 0) := "10101";
+ constant MOV_RR_DATA : std_logic_vector(4 downto 0) := "01111";
+ constant MOV_D_A : std_logic_vector(7 downto 0) := "11110101";
+ constant MOV_D_RR : std_logic_vector(4 downto 0) := "10001";
+ constant MOV_D_D : std_logic_vector(7 downto 0) := "10000101";
+ constant MOV_D_ATRI : std_logic_vector(6 downto 0) := "1000011";
+ constant MOV_D_DATA : std_logic_vector(7 downto 0) := "01110101";
+ constant MOV_ATRI_A : std_logic_vector(6 downto 0) := "1111011";
+ constant MOV_ATRI_D : std_logic_vector(6 downto 0) := "1010011";
+ constant MOV_ATRI_DATA : std_logic_vector(6 downto 0) := "0111011";
+ constant MOVC_A_ATDPTR : std_logic_vector(7 downto 0) := "10010011";
+ constant MOVC_A_ATPC : std_logic_vector(7 downto 0) := "10000011";
+ constant MOVX_A_ATRI : std_logic_vector(6 downto 0) := "1110001";
+ constant MOVX_A_ATDPTR : std_logic_vector(7 downto 0) := "11100000";
+ constant MOVX_ATRI_A : std_logic_vector(6 downto 0) := "1111001";
+ constant MOVX_ATDPTR_A : std_logic_vector(7 downto 0) := "11110000";
+ constant MOV_C_BIT : std_logic_vector(7 downto 0) := "10100010";
+ constant MOV_BIT_C : std_logic_vector(7 downto 0) := "10010010";
+ constant MOV_DPTR_DATA : std_logic_vector(7 downto 0) := "10010000";
+ constant MUL_AB : std_logic_vector(7 downto 0) := "10100100";
+ constant NOP : std_logic_vector(7 downto 0) := "00000000";
+ constant ORL_A_RR : std_logic_vector(4 downto 0) := "01001";
+ constant ORL_A_D : std_logic_vector(7 downto 0) := "01000101";
+ constant ORL_A_ATRI : std_logic_vector(6 downto 0) := "0100011";
+ constant ORL_A_DATA : std_logic_vector(7 downto 0) := "01000100";
+ constant ORL_D_A : std_logic_vector(7 downto 0) := "01000010";
+ constant ORL_D_DATA : std_logic_vector(7 downto 0) := "01000011";
+ constant ORL_C_BIT : std_logic_vector(7 downto 0) := "01110010";
+ constant ORL_C_NBIT : std_logic_vector(7 downto 0) := "10100000";
+ constant POP : std_logic_vector(7 downto 0) := "11010000";
+ constant PUSH : std_logic_vector(7 downto 0) := "11000000";
+ constant RET : std_logic_vector(7 downto 0) := "00100010";
+ constant RETI : std_logic_vector(7 downto 0) := "00110010";
+ constant RL_A : std_logic_vector(7 downto 0) := "00100011";
+ constant RLC_A : std_logic_vector(7 downto 0) := "00110011";
+ constant RR_A : std_logic_vector(7 downto 0) := "00000011";
+ constant RRC_A : std_logic_vector(7 downto 0) := "00010011";
+ constant SETB_C : std_logic_vector(7 downto 0) := "11010011";
+ constant SETB_BIT : std_logic_vector(7 downto 0) := "11010010";
+ constant SJMP : std_logic_vector(7 downto 0) := "10000000";
+ constant SUBB_A_RR : std_logic_vector(4 downto 0) := "10011";
+ constant SUBB_A_D : std_logic_vector(7 downto 0) := "10010101";
+ constant SUBB_A_ATRI : std_logic_vector(6 downto 0) := "1001011";
+ constant SUBB_A_DATA : std_logic_vector(7 downto 0) := "10010100";
+ constant SWAP_A : std_logic_vector(7 downto 0) := "11000100";
+ constant XCH_A_RR : std_logic_vector(4 downto 0) := "11001";
+ constant XCH_A_D : std_logic_vector(7 downto 0) := "11000101";
+ constant XCH_A_ATRI : std_logic_vector(6 downto 0) := "1100011";
+ constant XCHD_A_ATRI : std_logic_vector(6 downto 0) := "1101011";
+ constant XRL_A_RR : std_logic_vector(4 downto 0) := "01101";
+ constant XRL_A_D : std_logic_vector(7 downto 0) := "01100101";
+ constant XRL_A_ATRI : std_logic_vector(6 downto 0) := "0110011";
+ constant XRL_A_DATA : std_logic_vector(7 downto 0) := "01100100";
+ constant XRL_D_A : std_logic_vector(7 downto 0) := "01100010";
+ constant XRL_D_DATA : std_logic_vector(7 downto 0) := "01100011";
+
+
+ type t_state is (STARTUP,
+ FETCH,
+ EXEC1,
+ EXEC2,
+ EXEC3);
+
+ type t_instr_category is (IC_ACALL,
+ IC_ADD_A_RR,
+ IC_ADD_A_D,
+ IC_ADD_A_ATRI,
+ IC_ADD_A_DATA,
+ IC_ADDC_A_RR,
+ IC_ADDC_A_D,
+ IC_ADDC_A_ATRI,
+ IC_ADDC_A_DATA,
+ IC_AJMP,
+ IC_ANL_A_RR,
+ IC_ANL_A_D,
+ IC_ANL_A_ATRI,
+ IC_ANL_A_DATA,
+ IC_ANL_D_A,
+ IC_ANL_D_DATA,
+ IC_ANL_C_BIT,
+ IC_ANL_C_NBIT,
+ IC_CJNE_A_D,
+ IC_CJNE_A_DATA,
+ IC_CJNE_RR_DATA,
+ IC_CJNE_ATRI_DATA,
+ IC_CLR_A,
+ IC_CLR_C,
+ IC_CLR_BIT,
+ IC_CPL_A,
+ IC_CPL_C,
+ IC_CPL_BIT,
+ IC_DA_A,
+ IC_DEC_A,
+ IC_DEC_RR,
+ IC_DEC_D,
+ IC_DEC_ATRI,
+ IC_DIV_AB,
+ IC_DJNZ_RR,
+ IC_DJNZ_D,
+ IC_INC_A,
+ IC_INC_RR,
+ IC_INC_D,
+ IC_INC_ATRI,
+ IC_INC_DPTR,
+ IC_JB,
+ IC_JBC,
+ IC_JC,
+ IC_JMP_A_DPTR,
+ IC_JNB,
+ IC_JNC,
+ IC_JNZ,
+ IC_JZ,
+ IC_LCALL,
+ IC_LJMP,
+ IC_MOV_A_RR,
+ IC_MOV_A_D,
+ IC_MOV_A_ATRI,
+ IC_MOV_A_DATA,
+ IC_MOV_RR_A,
+ IC_MOV_RR_D,
+ IC_MOV_RR_DATA,
+ IC_MOV_D_A,
+ IC_MOV_D_RR,
+ IC_MOV_D_D,
+ IC_MOV_D_ATRI,
+ IC_MOV_D_DATA,
+ IC_MOV_ATRI_A,
+ IC_MOV_ATRI_D,
+ IC_MOV_ATRI_DATA,
+ IC_MOVC_A_ATDPTR,
+ IC_MOVC_A_ATPC,
+ IC_MOVX_A_ATRI,
+ IC_MOVX_A_ATDPTR,
+ IC_MOVX_ATRI_A,
+ IC_MOVX_ATDPTR_A,
+ IC_MOV_C_BIT,
+ IC_MOV_BIT_C,
+ IC_MOV_DPTR_DATA,
+ IC_MUL_AB,
+ IC_NOP,
+ IC_ORL_A_RR,
+ IC_ORL_A_D,
+ IC_ORL_A_ATRI,
+ IC_ORL_A_DATA,
+ IC_ORL_D_A,
+ IC_ORL_D_DATA,
+ IC_ORL_C_BIT,
+ IC_ORL_C_NBIT,
+ IC_POP,
+ IC_PUSH,
+ IC_RET,
+ IC_RETI,
+ IC_RL_A,
+ IC_RLC_A,
+ IC_RR_A,
+ IC_RRC_A,
+ IC_SETB_C,
+ IC_SETB_BIT,
+ IC_SJMP,
+ IC_SUBB_A_RR,
+ IC_SUBB_A_D,
+ IC_SUBB_A_ATRI,
+ IC_SUBB_A_DATA,
+ IC_SWAP_A,
+ IC_XCH_A_RR,
+ IC_XCH_A_D,
+ IC_XCH_A_ATRI,
+ IC_XCHD_A_ATRI,
+ IC_XRL_A_RR,
+ IC_XRL_A_D,
+ IC_XRL_A_ATRI,
+ IC_XRL_A_DATA,
+ IC_XRL_D_A,
+ IC_XRL_D_DATA);
+
+ type t_tmr_lv is array(C_IMPL_N_TMR-1 downto 0) of
+ std_logic_vector(7 downto 0);
+
+ type t_tmr_us is array(C_IMPL_N_TMR-1 downto 0) of unsigned(7 downto 0);
+
+ type t_tmr_us2 is array(C_IMPL_N_TMR-1 downto 0) of unsigned(1 downto 0);
+
+ type t_tmr_l is array(C_IMPL_N_TMR-1 downto 0) of std_logic;
+
+ type t_siu_lv is array(C_IMPL_N_SIU-1 downto 0) of
+ std_logic_vector(7 downto 0);
+
+ type t_siu_us is array(C_IMPL_N_SIU-1 downto 0) of unsigned(7 downto 0);
+
+ type t_siu_l is array(C_IMPL_N_SIU-1 downto 0) of std_logic;
+
+ type t_ext_l is array(C_IMPL_N_EXT-1 downto 0) of std_logic;
+
+
+ component addsub_cy
+ generic (DWIDTH : integer);
+ port (opa_i : in std_logic_vector(DWIDTH-1 downto 0);
+ opb_i : in std_logic_vector(DWIDTH-1 downto 0);
+ addsub_i : in std_logic;
+ cy_i : in std_logic;
+ cy_o : out std_logic;
+ rslt_o : out std_logic_vector(DWIDTH-1 downto 0));
+ end component;
+
+ component addsub_ovcy
+ generic (DWIDTH : integer);
+ port (opa_i : in std_logic_vector(DWIDTH-1 downto 0);
+ opb_i : in std_logic_vector(DWIDTH-1 downto 0);
+ addsub_i : in std_logic;
+ cy_i : in std_logic;
+ cy_o : out std_logic;
+ ov_o : out std_logic;
+ rslt_o : out std_logic_vector(DWIDTH-1 downto 0));
+ end component;
+
+ component addsub_core
+ generic (DWIDTH : integer);
+ port (opa_i : in std_logic_vector(DWIDTH-1 downto 0);
+ opb_i : in std_logic_vector(DWIDTH-1 downto 0);
+ addsub_i : in std_logic;
+ cy_i : in std_logic;
+ cy_o : out std_logic_vector((DWIDTH-1)/4 downto 0);
+ ov_o : out std_logic;
+ rslt_o : out std_logic_vector(DWIDTH-1 downto 0));
+ end component;
+
+ component alucore
+ generic (DWIDTH : integer);
+ port (op_a_i : in std_logic_vector(DWIDTH-1 downto 0);
+ op_b_i : in std_logic_vector(DWIDTH-1 downto 0);
+ alu_cmd_i : in std_logic_vector(3 downto 0);
+ cy_i : in std_logic_vector((DWIDTH-1)/4 downto 0);
+ cy_o : out std_logic_vector((DWIDTH-1)/4 downto 0);
+ result_o : out std_logic_vector(DWIDTH-1 downto 0));
+ end component;
+
+ component comb_divider
+ generic (
+ DWIDTH : integer);
+ port (
+ dvdnd_i : in std_logic_vector(DWIDTH-1 downto 0);
+ dvsor_i : in std_logic_vector(DWIDTH-1 downto 0);
+ qutnt_o : out std_logic_vector(DWIDTH-1 downto 0);
+ rmndr_o : out std_logic_vector(DWIDTH-1 downto 0));
+ end component;
+
+ component comb_mltplr
+ generic (
+ DWIDTH : integer);
+ port (
+ mltplcnd_i : in std_logic_vector(DWIDTH-1 downto 0);
+ mltplctr_i : in std_logic_vector(DWIDTH-1 downto 0);
+ product_o : out std_logic_vector((DWIDTH*2)-1 downto 0));
+ end component;
+
+ component dcml_adjust
+ generic (
+ DWIDTH : integer);
+ port (
+ data_i : in std_logic_vector(DWIDTH-1 downto 0);
+ cy_i : in std_logic_vector((DWIDTH-1)/4 downto 0);
+ data_o : out std_logic_vector(DWIDTH-1 downto 0);
+ cy_o : out std_logic);
+ end component;
+
+ component alumux
+ generic (DWIDTH : integer);
+ port (rom_data_i : in std_logic_vector(DWIDTH-1 downto 0);
+ ram_data_i : in std_logic_vector(DWIDTH-1 downto 0);
+ acc_i : in std_logic_vector(DWIDTH-1 downto 0);
+ cmd_i : in std_logic_vector(5 downto 0);
+ cy_i : in std_logic_vector((DWIDTH-1)/4 downto 0);
+ ov_i : in std_logic;
+ cy_o : out std_logic_vector((DWIDTH-1)/4 downto 0);
+ ov_o : out std_logic;
+ result_a_o : out std_logic_vector(DWIDTH-1 downto 0);
+ result_b_o : out std_logic_vector(DWIDTH-1 downto 0);
+ result_i : in std_logic_vector(DWIDTH-1 downto 0);
+ new_cy_i : in std_logic_vector((DWIDTH-1)/4 downto 0);
+ addsub_rslt_i : in std_logic_vector(DWIDTH-1 downto 0);
+ addsub_cy_i : in std_logic_vector((DWIDTH-1)/4 downto 0);
+ addsub_ov_i : in std_logic;
+ op_a_o : out std_logic_vector(DWIDTH-1 downto 0);
+ op_b_o : out std_logic_vector(DWIDTH-1 downto 0);
+ alu_cmd_o : out std_logic_vector(3 downto 0);
+ opa_o : out std_logic_vector(DWIDTH-1 downto 0);
+ opb_o : out std_logic_vector(DWIDTH-1 downto 0);
+ addsub_o : out std_logic;
+ addsub_cy_o : out std_logic;
+ dvdnd_o : out std_logic_vector(DWIDTH-1 downto 0);
+ dvsor_o : out std_logic_vector(DWIDTH-1 downto 0);
+ qutnt_i : in std_logic_vector(DWIDTH-1 downto 0);
+ rmndr_i : in std_logic_vector(DWIDTH-1 downto 0);
+ mltplcnd_o : out std_logic_vector(DWIDTH-1 downto 0);
+ mltplctr_o : out std_logic_vector(DWIDTH-1 downto 0);
+ product_i : in std_logic_vector((DWIDTH*2)-1 downto 0);
+ dcml_data_o : out std_logic_vector(DWIDTH-1 downto 0);
+ dcml_data_i : in std_logic_vector(DWIDTH-1 downto 0);
+ dcml_cy_i : in std_logic);
+ end component;
+
+ component mc8051_alu
+ generic (
+ DWIDTH : integer);
+ port (
+ rom_data_i : in std_logic_vector(DWIDTH-1 downto 0);
+ ram_data_i : in std_logic_vector(DWIDTH-1 downto 0);
+ acc_i : in std_logic_vector(DWIDTH-1 downto 0);
+ cmd_i : in std_logic_vector(5 downto 0);
+ cy_i : in std_logic_vector((DWIDTH-1)/4 downto 0);
+ ov_i : in std_logic;
+ new_cy_o : out std_logic_vector((DWIDTH-1)/4 downto 0);
+ new_ov_o : out std_logic;
+ result_a_o : out std_logic_vector(DWIDTH-1 downto 0);
+ result_b_o : out std_logic_vector(DWIDTH-1 downto 0));
+ end component;
+
+ component mc8051_siu
+ port (clk : in std_logic;
+ cen : in std_logic;
+ reset : in std_logic;
+ tf_i : in std_logic;
+ trans_i : in std_logic;
+ rxd_i : in std_logic;
+ scon_i : in std_logic_vector(5 downto 0);
+ sbuf_i : in std_logic_vector(7 downto 0);
+ smod_i : in std_logic;
+ sbuf_o : out std_logic_vector(7 downto 0);
+ scon_o : out std_logic_vector(2 downto 0);
+ rxdwr_o : out std_logic;
+ rxd_o : out std_logic;
+ txd_o : out std_logic);
+ end component;
+
+
+ component mc8051_tmrctr
+ port (clk : in std_logic;
+ cen : in std_logic;
+ reset : in std_logic;
+ int0_i : in std_logic;
+ int1_i : in std_logic;
+ t0_i : in std_logic;
+ t1_i : in std_logic;
+ tmod_i : in std_logic_vector(7 downto 0);
+ tcon_tr0_i : in std_logic;
+ tcon_tr1_i : in std_logic;
+ reload_i : in std_logic_vector(7 downto 0);
+ wt_en_i : in std_logic;
+ wt_i : in std_logic_vector(1 downto 0);
+ th0_o : out std_logic_vector(7 downto 0);
+ tl0_o : out std_logic_vector(7 downto 0);
+ th1_o : out std_logic_vector(7 downto 0);
+ tl1_o : out std_logic_vector(7 downto 0);
+ tf0_o : out std_logic;
+ tf1_o : out std_logic);
+ end component;
+
+
+ component control_fsm
+ port ( state_i : in t_state; -- actual state
+ help_i : in std_logic_vector (7 downto 0); -- general help-reg
+ bit_data_i : in std_logic; -- bitdata from regs
+ aludata_i : in std_logic_vector (7 downto 0); -- ALU result
+ command_i : in std_logic_vector (7 downto 0); -- actual command
+ inthigh_i : in std_logic; -- high priority int is running
+ intlow_i : in std_logic; -- low priority int is running
+ intpre_i : in std_logic; -- an interrupt must start
+ intpre2_i : in std_logic; -- prepare for interrupt
+ intblock_i : in std_logic; -- interrupt delay at RETI, IE, IP
+ ti_i : in std_logic;
+ ri_i : in std_logic;
+ ie0_i : in std_logic;
+ ie1_i : in std_logic;
+ tf0_i : in std_logic;
+ tf1_i : in std_logic;
+ acc : in std_logic_vector(7 downto 0);
+ psw : in std_logic_vector(7 downto 0);
+ ie : in std_logic_vector(7 downto 0);
+ ip : in std_logic_vector(7 downto 0);
+
+ alu_cmd_o : out std_logic_vector (5 downto 0); -- ALU code
+ pc_inc_en_o : out std_logic_vector (3 downto 0);
+ nextstate_o : out t_state;
+ adr_mux_o : out std_logic_vector (3 downto 0);
+ adrx_mux_o : out std_logic_vector (1 downto 0);
+ wrx_mux_o : out std_logic;
+ data_mux_o : out std_logic_vector (3 downto 0);
+ bdata_mux_o : out std_logic_vector (3 downto 0);
+ regs_wr_en_o : out std_logic_vector (2 downto 0);
+ help_en_o : out std_logic_vector (3 downto 0);
+ help16_en_o : out std_logic_vector (1 downto 0);
+ helpb_en_o : out std_logic;
+ inthigh_en_o : out std_logic;
+ intlow_en_o : out std_logic;
+ intpre2_en_o : out std_logic;
+ inthigh_d_o : out std_logic;
+ intlow_d_o : out std_logic;
+ intpre2_d_o : out std_logic;
+ ext0isr_d_o : out std_logic;
+ ext1isr_d_o : out std_logic;
+ ext0isrh_d_o : out std_logic;
+ ext1isrh_d_o : out std_logic;
+ ext0isr_en_o : out std_logic;
+ ext1isr_en_o : out std_logic;
+ ext0isrh_en_o : out std_logic;
+ ext1isrh_en_o : out std_logic);
+
+ end component;
+
+ component control_mem
+ port (pc_o : out std_logic_vector(15 downto 0);
+ rom_data_i : in std_logic_vector(7 downto 0);
+ ram_data_o : out std_logic_vector(7 downto 0);
+ ram_data_i : in std_logic_vector(7 downto 0);
+ ram_adr_o : out std_logic_vector(6 downto 0);
+ reg_data_o : out std_logic_vector(7 downto 0);
+ ram_wr_o : out std_logic;
+ cy_o : out std_logic_vector(1 downto 0);
+ ov_o : out std_logic;
+ ram_en_o : out std_logic;
+ aludata_i : in std_logic_vector (7 downto 0);
+ aludatb_i : in std_logic_vector (7 downto 0);
+ acc_o : out std_logic_vector (7 downto 0);
+ new_cy_i : in std_logic_vector(1 downto 0);
+ new_ov_i : in std_logic;
+ reset : in std_logic;
+ clk : in std_logic;
+ cen : in std_logic;
+ int0_i : in std_logic_vector(C_IMPL_N_EXT-1 downto 0);
+ int1_i : in std_logic_vector(C_IMPL_N_EXT-1 downto 0);
+ p0_i : in std_logic_vector(7 downto 0);
+ p1_i : in std_logic_vector(7 downto 0);
+ p2_i : in std_logic_vector(7 downto 0);
+ p3_i : in std_logic_vector(7 downto 0);
+ p0_o : out std_logic_vector(7 downto 0);
+ p1_o : out std_logic_vector(7 downto 0);
+ p2_o : out std_logic_vector(7 downto 0);
+ p3_o : out std_logic_vector(7 downto 0);
+ all_trans_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ all_scon_o : out std_logic_vector(6*C_IMPL_N_SIU-1 downto 0);
+ all_sbuf_o : out std_logic_vector(8*C_IMPL_N_SIU-1 downto 0);
+ all_smod_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ all_scon_i : in std_logic_vector(3*C_IMPL_N_SIU-1 downto 0);
+ all_sbuf_i : in std_logic_vector(8*C_IMPL_N_SIU-1 downto 0);
+ all_tcon_tr0_o : out std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_tcon_tr1_o : out std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_tmod_o : out std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_reload_o : out std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_wt_o : out std_logic_vector(2*C_IMPL_N_TMR-1 downto 0);
+ all_wt_en_o : out std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_tf0_i : in std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_tf1_i : in std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_tl0_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_tl1_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_th0_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_th1_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ state_o : out t_state;
+ help_o : out std_logic_vector(7 downto 0);
+ bit_data_o : out std_logic;
+ command_o : out std_logic_vector (7 downto 0);
+ inthigh_o : out std_logic;
+ intlow_o : out std_logic;
+ intpre_o : out std_logic;
+ intpre2_o : out std_logic;
+ intblock_o : out std_logic;
+ ti_o : out std_logic;
+ ri_o : out std_logic;
+ ie0_o : out std_logic;
+ ie1_o : out std_logic;
+ tf0_o : out std_logic;
+ tf1_o : out std_logic;
+ psw_o : out std_logic_vector(7 downto 0);
+ ie_o : out std_logic_vector(7 downto 0);
+ ip_o : out std_logic_vector(7 downto 0);
+ adrx_o : out std_logic_vector(15 downto 0);
+ datax_o : out std_logic_vector(7 downto 0);
+ memx_o : out std_logic;
+ wrx_o : out std_logic;
+ datax_i : in std_logic_vector(7 downto 0);
+ pc_inc_en_i : in std_logic_vector (3 downto 0);
+ nextstate_i : in t_state;
+ adr_mux_i : in std_logic_vector (3 downto 0);
+ adrx_mux_i : in std_logic_vector (1 downto 0);
+ wrx_mux_i : in std_logic;
+ data_mux_i : in std_logic_vector (3 downto 0);
+ bdata_mux_i : in std_logic_vector (3 downto 0);
+ regs_wr_en_i : in std_logic_vector (2 downto 0);
+ help_en_i : in std_logic_vector (3 downto 0);
+ help16_en_i : in std_logic_vector (1 downto 0);
+ helpb_en_i : in std_logic;
+ inthigh_en_i : in std_logic;
+ intlow_en_i : in std_logic;
+ intpre2_en_i : in std_logic;
+ inthigh_d_i : in std_logic;
+ intlow_d_i : in std_logic;
+ intpre2_d_i : in std_logic;
+ ext0isr_d_i : in std_logic;
+ ext1isr_d_i : in std_logic;
+ ext0isrh_d_i : in std_logic;
+ ext1isrh_d_i : in std_logic;
+ ext0isr_en_i : in std_logic;
+ ext1isr_en_i : in std_logic;
+ ext0isrh_en_i : in std_logic;
+ ext1isrh_en_i : in std_logic);
+
+ end component;
+
+ component mc8051_control
+ port (pc_o : out std_logic_vector(15 downto 0);
+ rom_data_i : in std_logic_vector(7 downto 0);
+ ram_data_o : out std_logic_vector(7 downto 0);
+ ram_data_i : in std_logic_vector(7 downto 0);
+ ram_adr_o : out std_logic_vector(6 downto 0);
+ reg_data_o : out std_logic_vector(7 downto 0);
+ ram_wr_o : out std_logic;
+ cy_o : out std_logic_vector(1 downto 0);
+ ov_o : out std_logic;
+ ram_en_o : out std_logic;
+ alu_cmd_o : out std_logic_vector (5 downto 0);
+ aludata_i : in std_logic_vector (7 downto 0);
+ aludatb_i : in std_logic_vector (7 downto 0);
+ acc_o : out std_logic_vector (7 downto 0);
+ new_cy_i : in std_logic_vector(1 downto 0);
+ new_ov_i : in std_logic;
+ reset : in std_logic;
+ clk : in std_logic;
+ cen : in std_logic;
+ int0_i : in std_logic_vector(C_IMPL_N_EXT-1 downto 0);
+ int1_i : in std_logic_vector(C_IMPL_N_EXT-1 downto 0);
+ datax_i : in std_logic_vector (7 downto 0);
+ datax_o : out std_logic_vector (7 downto 0);
+ adrx_o : out std_logic_vector (15 downto 0);
+ memx_o : out std_logic;
+ wrx_o : out std_logic;
+ p0_i : in std_logic_vector(7 downto 0);
+ p1_i : in std_logic_vector(7 downto 0);
+ p2_i : in std_logic_vector(7 downto 0);
+ p3_i : in std_logic_vector(7 downto 0);
+ p0_o : out std_logic_vector(7 downto 0);
+ p1_o : out std_logic_vector(7 downto 0);
+ p2_o : out std_logic_vector(7 downto 0);
+ p3_o : out std_logic_vector(7 downto 0);
+ all_trans_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ all_scon_o : out std_logic_vector(6*C_IMPL_N_SIU-1 downto 0);
+ all_sbuf_o : out std_logic_vector(8*C_IMPL_N_SIU-1 downto 0);
+ all_smod_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ all_scon_i : in std_logic_vector(3*C_IMPL_N_SIU-1 downto 0);
+ all_sbuf_i : in std_logic_vector(8*C_IMPL_N_SIU-1 downto 0);
+ all_tcon_tr0_o : out std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_tcon_tr1_o : out std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_tmod_o : out std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_reload_o : out std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_wt_o : out std_logic_vector(2*C_IMPL_N_TMR-1 downto 0);
+ all_wt_en_o : out std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_tf0_i : in std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_tf1_i : in std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_tl0_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_tl1_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_th0_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0);
+ all_th1_i : in std_logic_vector(8*C_IMPL_N_TMR-1 downto 0));
+
+ end component;
+
+
+ component mc8051_core
+ port (clk : in std_logic;
+ cen : in std_logic;
+ reset : in std_logic;
+ rom_data_i : in std_logic_vector(7 downto 0);
+ ram_data_i : in std_logic_vector(7 downto 0);
+ int0_i : in std_logic_vector(C_IMPL_N_EXT-1 downto 0);
+ int1_i : in std_logic_vector(C_IMPL_N_EXT-1 downto 0);
+ all_t0_i : in std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_t1_i : in std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_rxd_i : in std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ p0_i : in std_logic_vector(7 downto 0);
+ p1_i : in std_logic_vector(7 downto 0);
+ p2_i : in std_logic_vector(7 downto 0);
+ p3_i : in std_logic_vector(7 downto 0);
+ p0_o : out std_logic_vector(7 downto 0);
+ p1_o : out std_logic_vector(7 downto 0);
+ p2_o : out std_logic_vector(7 downto 0);
+ p3_o : out std_logic_vector(7 downto 0);
+ all_rxd_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ all_txd_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ all_rxdwr_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ rom_adr_o : out std_logic_vector(15 downto 0);
+ ram_data_o : out std_logic_vector(7 downto 0);
+ ram_adr_o : out std_logic_vector(6 downto 0);
+ ram_wr_o : out std_logic;
+ ram_en_o : out std_logic;
+ datax_i : in std_logic_vector (7 downto 0);
+ datax_o : out std_logic_vector (7 downto 0);
+ adrx_o : out std_logic_vector (15 downto 0);
+ memx_o : out std_logic;
+ wrx_o : out std_logic);
+
+ end component;
+
+
+ component mc8051_top
+ port (clk : in std_logic;
+ cen : in std_logic;
+ reset : in std_logic;
+ int0_i : in std_logic_vector(C_IMPL_N_EXT-1 downto 0);
+ int1_i : in std_logic_vector(C_IMPL_N_EXT-1 downto 0);
+ all_t0_i : in std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_t1_i : in std_logic_vector(C_IMPL_N_TMR-1 downto 0);
+ all_rxd_i : in std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ p0_i : in std_logic_vector(7 downto 0);
+ p1_i : in std_logic_vector(7 downto 0);
+ p2_i : in std_logic_vector(7 downto 0);
+ p3_i : in std_logic_vector(7 downto 0);
+ p0_o : out std_logic_vector(7 downto 0);
+ p1_o : out std_logic_vector(7 downto 0);
+ p2_o : out std_logic_vector(7 downto 0);
+ p3_o : out std_logic_vector(7 downto 0);
+ all_rxd_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ all_txd_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0);
+ all_rxdwr_o : out std_logic_vector(C_IMPL_N_SIU-1 downto 0));
+
+ end component;
+
+ -----------------------------------------------------------------------------
+ -- START: Component declarations for simulation models
+ -----------------------------------------------------------------------------
+ component mc8051_ram
+ port (clk : in std_logic;
+ cen : in std_logic;
+ reset : in std_logic;
+ ram_data_i : in std_logic_vector(7 downto 0);
+ ram_data_o : out std_logic_vector(7 downto 0);
+ ram_adr_i : in std_logic_vector(6 downto 0);
+ ram_wr_i : in std_logic;
+ ram_en_i : in std_logic);
+
+ end component;
+
+ component mc8051_ramx
+ port (clk : in std_logic;
+ cen : in std_logic;
+ reset : in std_logic;
+ ram_data_i : in std_logic_vector(7 downto 0);
+ ram_data_o : out std_logic_vector(7 downto 0);
+ ram_adr_i : in std_logic_vector(15 downto 0);
+ ram_wr_i : in std_logic);
+
+ end component;
+
+ component mc8051_rom
+ port (clk : in std_logic;
+ cen : in std_logic;
+ reset : in std_logic;
+ rom_data_o : out std_logic_vector(7 downto 0);
+ rom_adr_i : in std_logic_vector(15 downto 0));
+
+ end component;
+ -----------------------------------------------------------------------------
+ -- END: Component declarations for simulation models
+ -----------------------------------------------------------------------------
+
+
+end mc8051_p;
diff --git a/testsuite/synth/issue2273/mc8051_siu_.vhd b/testsuite/synth/issue2273/mc8051_siu_.vhd
new file mode 100644
index 000000000..2967fd83d
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_siu_.vhd
@@ -0,0 +1,92 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: mc8051_siu_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.5 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:45 $
+--
+--
+-- Description: Serial interface unit for the mc8051 microcontroller.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+-----------------------------ENTITY DECLARATION--------------------------------
+
+entity mc8051_siu is
+
+ port (clk : in std_logic; --< system clock
+ cen : in std_logic; --< system clock enable
+ reset : in std_logic; --< system reset
+ tf_i : in std_logic; --< timer1 overflow flag
+ trans_i : in std_logic; --< 1 activates transm.
+ rxd_i : in std_logic; --< serial data input
+ scon_i : in std_logic_vector(5 downto 0); --< from SFR register
+ --< bits 7 to 3
+ sbuf_i : in std_logic_vector(7 downto 0); --< data for transm.
+ smod_i : in std_logic; --< low(0)/high baudrate
+
+ sbuf_o : out std_logic_vector(7 downto 0); --< received data
+ scon_o : out std_logic_vector(2 downto 0); --< to SFR register
+ --< bits 0 to 2
+ rxdwr_o : out std_logic; --< rxd direction signal
+ rxd_o : out std_logic; --< mode0 data output
+ txd_o : out std_logic); --< serial data output
+
+end mc8051_siu;
+
diff --git a/testsuite/synth/issue2273/mc8051_siu_rtl.vhd b/testsuite/synth/issue2273/mc8051_siu_rtl.vhd
new file mode 100644
index 000000000..b3a9282f1
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_siu_rtl.vhd
@@ -0,0 +1,1202 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: mc8051_siu_rtl.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.10 $
+--
+-- Date of Latest Version: $Date: 2010-03-24 10:20:48 $
+--
+--
+-- Description: Serial interface unit for the mc8051 microcontroller.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture rtl of mc8051_siu is
+
+ signal s_rxpre_count : unsigned(5 downto 0); -- Receive prescaler
+ signal s_txpre_count : unsigned(5 downto 0); -- Transmit prescaler
+ signal s_m0_shift_en : std_logic; -- masks out every twelfth
+ -- rising edge of clk
+ signal s_m2_rxshift_en : std_logic; -- mode 2 shift enable
+ signal s_m13_rxshift_en : std_logic; -- mode 1 and 3 shift enable
+ signal s_m2_txshift_en : std_logic; -- mode 2 shift enable
+ signal s_m13_txshift_en : std_logic; -- mode 1 and 3 shift enable
+ signal s_ff0 : std_logic; -- flipflop for edge dedection
+ signal s_ff1 : std_logic; -- flipflop for edge dedection
+ signal s_tf : std_logic; -- synchronised timer flag
+ signal s_mode : unsigned(1 downto 0); -- mode
+ signal s_sm2 : std_logic; -- multi processor comm. bit
+ signal s_detect : std_logic; -- indicates start of recept.
+ signal s_ren : std_logic; -- receive enable
+ signal s_rxd_val : std_logic; -- received data bit
+ signal s_txdm0 : std_logic; -- shift clock for m0
+ signal s_ri : std_logic; -- external receive interrupt
+ signal s_trans : std_logic; -- enable transmission
+ signal s_recv_done : std_logic; -- receive interrupt
+ signal s_tran_done : std_logic; -- transmit interrupt
+ signal s_rb8 : std_logic; -- 8th data bit
+ signal s_tb8 : std_logic; -- 8th data bit
+ signal s_recv_state : unsigned(3 downto 0); -- state reg. of receive unit
+ signal s_tran_state : unsigned(3 downto 0); -- state reg. of transmit unit
+ signal s_rxd_ff0 : std_logic; -- sample flip-flop
+ signal s_rxd_ff1 : std_logic; -- sample flip-flop
+ signal s_rxd_ff2 : std_logic; -- sample flip-flop
+ signal s_det_ff0 : std_logic; -- rec. detect flip-flop
+ signal s_det_ff1 : std_logic; -- rec. detect flip-flop
+ signal s_tran_sh : unsigned(10 downto 0); -- transmission shift register
+ signal s_recv_sh : unsigned(7 downto 0); -- reception shift register
+ signal s_recv_buf : unsigned(7 downto 0); -- reception buffer register
+ signal s_rxm13_ff0 : std_logic; -- generates an enable singal
+ signal s_rxm13_ff1 : std_logic; -- generates an enable singal
+ signal s_txm13_ff0 : std_logic; -- generates an enable singal
+ signal s_txm13_ff1 : std_logic; -- generates an enable singal
+
+begin -- architecture rtl
+
+ s_mode(1) <= scon_i(4); -- defines the 4 operating modes
+ s_mode(0) <= scon_i(3);
+ s_ren <= scon_i(1); -- receive enable
+ s_sm2 <= scon_i(2); -- 1 time or half time baud rate
+ s_tb8 <= scon_i(0); -- 9th data bit for transmission
+ s_ri <= scon_i(5); -- the receive interrupt bit of the
+ -- control unit
+ sbuf_o <= std_logic_vector(s_recv_buf); -- the receive buffer output
+ scon_o(0) <= s_recv_done; -- set when reception is completed
+ scon_o(1) <= s_tran_done; -- set when transmission is completed
+ scon_o(2) <= s_rb8; -- 9th data bit of reception
+
+-------------------------------------------------------------------------------
+ -- The two flip flops are updated every rising clock edge of clk.
+ -- If a rising edge
+ -- on the port tf_i is dedected the signal s_tf is set to 1 for one period.
+ --
+ -- The transmission start signal s_trans is generated and held high till
+ -- the statemachine has been launched with its first shift.
+ --
+ -- The shift clock for mode0 is generated. It toggles with the half
+ -- s_m0_shift_en rate.
+
+ s_tf <= '1' when (s_ff0 = '1' and s_ff1 = '0') else '0';
+
+ p_sample_tf: process (clk, cen, reset)
+
+ begin
+
+ if reset = '1' then
+ s_ff0 <= '0';
+ s_ff1 <= '0';
+ s_trans <= '0';
+ else
+ if clk'event and clk = '1' and cen='1' then
+ s_ff0 <= tf_i;
+ s_ff1 <= s_ff0;
+
+ if trans_i = '1' then
+ s_trans <= '1';
+ else
+ case s_mode is
+ when ("00") =>
+ if s_m0_shift_en = '1' then
+ s_trans <= '0';
+ end if;
+ when ("01") =>
+ if s_m13_txshift_en = '1' then
+ s_trans <= '0';
+ end if;
+ when ("10") =>
+ if s_m2_txshift_en = '1' then
+ s_trans <= '0';
+ end if;
+ when others =>
+ if s_m13_txshift_en = '1' then
+ s_trans <= '0';
+ end if;
+ end case;
+ end if;
+ end if;
+ end if;
+
+ end process p_sample_tf;
+
+
+-------------------------------------------------------------------------------
+ -- The register s_rxpre_count is driven with the system clock clk. So a
+ -- good enable signal (which is stable when clk has its rising edge) can be
+ -- derived to mask out every pulse of clk needed.
+ -- s_m0_shift_en activates every twelfth clock cycle
+ -- s_m2_shift_en activates baud rates of 1/32 or 1/64 the clock frequenzy
+ -- depending on signal smod_i
+ -- s_m13_shift_en activates baud rates depending on timer/counter1 flag
+
+ s_m0_shift_en <= '1' when s_txpre_count(3 downto 0) = conv_unsigned(11,5)
+ else '0';
+
+ s_m2_rxshift_en <= '1' when (s_rxpre_count(4 downto 0) = conv_unsigned(31,5)
+ and smod_i = '1') or
+ (s_rxpre_count = conv_unsigned(63,6)
+ and smod_i = '0')
+ else '0';
+ s_m13_rxshift_en <= '1' when s_rxm13_ff0 = '1' and s_rxm13_ff1 = '0'
+ else '0';
+
+ s_m2_txshift_en <= '1' when (s_txpre_count(4 downto 0) = conv_unsigned(31,5)
+ and smod_i = '1') or
+ (s_txpre_count = conv_unsigned(63,6)
+ and smod_i = '0')
+ else '0';
+ s_m13_txshift_en <= '1' when s_txm13_ff0 = '1' and s_txm13_ff1 = '0'
+ else '0';
+
+ p_divide_clk: process (clk, cen, reset)
+
+ begin
+
+ if reset = '1' then
+ s_rxpre_count <= conv_unsigned(0,6);
+ s_txpre_count <= conv_unsigned(0,6);
+ s_rxm13_ff0 <= '0';
+ s_rxm13_ff1 <= '0';
+ s_txm13_ff0 <= '0';
+ s_txm13_ff1 <= '0';
+ else
+ if clk'event and clk='1' and cen='1' then
+
+ s_rxm13_ff1 <= s_rxm13_ff0;
+ s_txm13_ff1 <= s_txm13_ff0;
+
+ if trans_i = '1' then
+ s_txpre_count <= conv_unsigned(0,6);
+ else
+ if s_mode=conv_unsigned(0,2) then
+ s_txpre_count <= s_txpre_count + conv_unsigned(1,1);
+ if s_txpre_count = conv_unsigned(11,6) then
+ s_txpre_count <= conv_unsigned(0,6);
+ end if;
+ elsif s_mode=conv_unsigned(2,2) then
+ s_txpre_count <= s_txpre_count + conv_unsigned(1,1);
+ else
+ if s_tf = '1' then
+ s_txpre_count <= s_txpre_count + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+
+ if s_detect = '1' then
+ s_rxpre_count <= conv_unsigned(0,6);
+ else
+ if s_mode=conv_unsigned(0,2) then
+ s_rxpre_count <= s_rxpre_count + conv_unsigned(1,1);
+ if s_rxpre_count = conv_unsigned(11,6) then
+ s_rxpre_count <= conv_unsigned(0,6);
+ end if;
+ elsif s_mode=conv_unsigned(2,2) then
+ s_rxpre_count <= s_rxpre_count + conv_unsigned(1,1);
+ else
+ if s_tf = '1' then
+ s_rxpre_count <= s_rxpre_count + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+
+ if smod_i = '1' then
+ if s_rxpre_count(3 downto 0) = conv_unsigned(15,4) then
+ s_rxm13_ff0 <= '1';
+ else
+ s_rxm13_ff0 <= '0';
+ end if;
+ else
+ if s_rxpre_count(4 downto 0) = conv_unsigned(31,5) then
+ s_rxm13_ff0 <= '1';
+ else
+ s_rxm13_ff0 <= '0';
+ end if;
+ end if;
+
+ if smod_i = '1' then
+ if s_txpre_count(3 downto 0) = conv_unsigned(15,4) then
+ s_txm13_ff0 <= '1';
+ else
+ s_txm13_ff0 <= '0';
+ end if;
+ else
+ if s_txpre_count(4 downto 0) = conv_unsigned(31,5) then
+ s_txm13_ff0 <= '1';
+ else
+ s_txm13_ff0 <= '0';
+ end if;
+ end if;
+
+ end if;
+ end if;
+
+ end process p_divide_clk;
+
+-------------------------------------------------------------------------------
+ -- This section samples the serial input for data detection, that is a
+ -- 1-to-0 transition at rxd in state "0000".
+ -- In all other states this unit reads the data bits depending on the baud
+ -- rate. In mode0 this section is not active.
+
+ s_detect <= '1' when s_det_ff0 = '0' and s_det_ff1 = '1' else '0';
+ s_rxd_val <= '1' when (s_rxd_ff0 = '1' and s_rxd_ff1 = '1') or
+ (s_rxd_ff0 = '1' and s_rxd_ff2 = '1') or
+ (s_rxd_ff1 = '1' and s_rxd_ff2 = '1') else '0';
+
+ p_sample_rx: process (clk, cen, reset)
+ begin
+ if reset = '1' then
+ s_rxd_ff0 <= '0';
+ s_rxd_ff1 <= '0';
+ s_rxd_ff2 <= '0';
+ s_det_ff0 <= '0';
+ s_det_ff1 <= '0';
+ else
+ if clk'event and clk='1' and cen='1' then
+ if s_recv_state = conv_unsigned(0,4) then -- state "0000" means
+ if s_ren = '1' then -- to listen for a 1 to 0
+ case s_mode is -- transition
+ when ("01") | ("11") =>
+ if smod_i = '1' then
+ if s_tf = '1' then
+ s_det_ff0 <= rxd_i;
+ s_det_ff1 <= s_det_ff0;
+ end if;
+ else
+ if s_rxpre_count(0) = '1' then
+ s_det_ff0 <= rxd_i;
+ s_det_ff1 <= s_det_ff0;
+ end if;
+ end if;
+ when ("10") =>
+ if smod_i = '1' then
+ if s_rxpre_count(0) = '1' then
+ s_det_ff0 <= rxd_i;
+ s_det_ff1 <= s_det_ff0;
+ end if;
+ else
+ if s_rxpre_count(1) = '1' then
+ s_det_ff0 <= rxd_i;
+ s_det_ff1 <= s_det_ff0;
+ end if;
+ end if;
+ when others =>
+ null;
+ end case;
+ else
+ s_det_ff0 <= '0';
+ s_det_ff1 <= '0';
+ end if;
+ else -- in all other states
+ s_det_ff0 <= '0';
+ s_det_ff1 <= '0';
+ if s_ren = '1' then -- sample for data bits
+ case s_mode is
+ when ("01") | ("11") =>
+ if smod_i = '1' then
+ if s_rxpre_count(3 downto 0) = conv_unsigned(7,4) or
+ s_rxpre_count(3 downto 0) = conv_unsigned(8,4) or
+ s_rxpre_count(3 downto 0) = conv_unsigned(9,4) then
+ s_rxd_ff0 <= rxd_i;
+ s_rxd_ff1 <= s_rxd_ff0;
+ s_rxd_ff2 <= s_rxd_ff1;
+ end if;
+ else
+ if s_rxpre_count(4 downto 0) = conv_unsigned(14,5) or
+ s_rxpre_count(4 downto 0) = conv_unsigned(16,5) or
+ s_rxpre_count(4 downto 0) = conv_unsigned(18,5) then
+ s_rxd_ff0 <= rxd_i;
+ s_rxd_ff1 <= s_rxd_ff0;
+ s_rxd_ff2 <= s_rxd_ff1;
+ end if;
+ end if;
+ when ("10") =>
+ if smod_i = '1' then
+ if s_rxpre_count(4 downto 0) = conv_unsigned(14,5) or
+ s_rxpre_count(4 downto 0) = conv_unsigned(16,5) or
+ s_rxpre_count(4 downto 0) = conv_unsigned(18,5) then
+ s_rxd_ff0 <= rxd_i;
+ s_rxd_ff1 <= s_rxd_ff0;
+ s_rxd_ff2 <= s_rxd_ff1;
+ end if;
+ else
+ if s_rxpre_count(5 downto 0) = conv_unsigned(28,6) or
+ s_rxpre_count(5 downto 0) = conv_unsigned(32,6) or
+ s_rxpre_count(5 downto 0) = conv_unsigned(36,6) then
+ s_rxd_ff0 <= rxd_i;
+ s_rxd_ff1 <= s_rxd_ff0;
+ s_rxd_ff2 <= s_rxd_ff1;
+ end if;
+ end if;
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+ end if;
+ end if;
+
+ end process p_sample_rx;
+
+
+-------------------------------------------------------------------------------
+--*************************** TRANSMIT ****************************************
+-- This is the finit state machine for the transmit shift register
+-------------------------------------------------------------------------------
+
+ txd_o <= s_txdm0;
+
+ p_transmit : process (clk, cen, reset)
+
+ variable v_txstep : std_logic_vector(1 downto 0);
+
+ begin
+
+ if reset = '1' then
+ s_tran_state <= conv_unsigned(0, 4);
+ s_tran_sh <= conv_unsigned(0, 11);
+ s_tran_done <= '0';
+
+ s_txdm0 <= '1';
+ rxd_o <= '1';
+ rxdwr_o <= '0';
+ else
+ if clk'event and clk = '1' and cen='1' then
+
+ -- Set default behavior
+ v_txstep := "00";
+
+ case s_mode is
+-------------------------------------------------------------------------------
+-- MODE 0
+-------------------------------------------------------------------------------
+ when ("00") =>
+
+ if s_tran_state = conv_unsigned(1, 4) or
+ s_tran_state = conv_unsigned(2, 4) or
+ s_tran_state = conv_unsigned(3, 4) or
+ s_tran_state = conv_unsigned(4, 4) or
+ s_tran_state = conv_unsigned(5, 4) or
+ s_tran_state = conv_unsigned(6, 4) or
+ s_tran_state = conv_unsigned(7, 4) or
+ s_tran_state = conv_unsigned(8, 4) or
+ s_recv_state = conv_unsigned(1, 4) or
+ s_recv_state = conv_unsigned(2, 4) or
+ s_recv_state = conv_unsigned(3, 4) or
+ s_recv_state = conv_unsigned(4, 4) or
+ s_recv_state = conv_unsigned(5, 4) or
+ s_recv_state = conv_unsigned(6, 4) or
+ s_recv_state = conv_unsigned(7, 4) or
+ s_recv_state = conv_unsigned(8, 4) then
+ if s_txpre_count(3 downto 0) = conv_unsigned(14, 4) or
+ s_txpre_count(3 downto 0) = conv_unsigned(6, 4) then
+ s_txdm0 <= not(s_txdm0);
+ end if;
+ else
+ s_txdm0 <= '1';
+ end if;
+
+ if s_m0_shift_en = '1' then
+ case s_tran_state is
+ when ("0001") => -- D1
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when ("0010") => -- D2
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when ("0011") => -- D3
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when ("0100") => -- D4
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when ("0101") => -- D5
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when ("0110") => -- D6
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when ("0111") => -- D7
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when ("1000") => -- D8, STOP BIT
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ s_tran_done <= '1';
+ v_txstep := "10";
+ rxd_o <= s_tran_sh(1);
+ rxdwr_o <= '1';
+ when others => -- D0
+ -- commence transmission if conditions are met
+ rxdwr_o <= '0';
+ if s_trans = '1' then
+ s_tran_sh(10 downto 8) <= conv_unsigned(7, 3);
+ s_tran_sh(7 downto 0) <= unsigned(sbuf_i);
+ v_txstep := "01";
+ s_tran_done <= '0';
+ rxd_o <= sbuf_i(0);
+ rxdwr_o <= '1';
+ end if;
+ end case;
+ end if;
+-------------------------------------------------------------------------------
+-- MODE 1
+-------------------------------------------------------------------------------
+ when ("01") =>
+ rxdwr_o <= '0';
+ rxd_o <= '0';
+ case s_tran_state is
+ when ("0001") => -- D1
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0010") => -- D2
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0011") => -- D3
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0100") => -- D4
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0101") => -- D5
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0110") => -- D6
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0111") => -- D7
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1000") => -- D8
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1001") => -- D9, set done bit
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ s_tran_done <= '1';
+ v_txstep := "10";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when others => -- D0
+ -- commence transmission if conditions are met
+ s_txdm0 <= '1';
+ if s_m13_txshift_en = '1' then
+ if s_trans = '1' then
+ s_tran_sh(10 downto 9) <= conv_unsigned(3, 2);
+ s_tran_sh(8 downto 1) <= unsigned(sbuf_i);
+ s_tran_sh(0) <= '0';
+ v_txstep := "01";
+ s_tran_done <= '0';
+ s_txdm0 <= '0';
+ end if;
+ end if;
+ end case;
+-------------------------------------------------------------------------------
+-- MODE 2
+-------------------------------------------------------------------------------
+ when ("10") =>
+ rxdwr_o <= '0';
+ rxd_o <= '0';
+ case s_tran_state is
+ when ("0001") => -- D1
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0010") => -- D2
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0011") => -- D3
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0100") => -- D4
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0101") => -- D5
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0110") => -- D6
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0111") => -- D7
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1000") => -- D8
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1001") => -- D9
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1010") => -- D10, set done bit
+ if s_m2_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ s_tran_done <= '1';
+ v_txstep := "10";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when others => -- D0
+ -- commence transmission if conditions are met
+ s_txdm0 <= '1';
+ if s_m2_txshift_en = '1' then
+ if s_trans = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9) <= s_tb8;
+ s_tran_sh(8 downto 1) <= unsigned(sbuf_i);
+ s_tran_sh(0) <= '0';
+ v_txstep := "01";
+ s_tran_done <= '0';
+ s_txdm0 <= '0';
+ end if;
+ end if;
+ end case;
+-------------------------------------------------------------------------------
+-- MODE 3
+-------------------------------------------------------------------------------
+ when ("11") =>
+ rxd_o <= '0';
+ rxdwr_o <= '0';
+ case s_tran_state is
+ when ("0001") => -- D1
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0010") => -- D2
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0011") => -- D3
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0100") => -- D4
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0101") => -- D5
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0110") => -- D6
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("0111") => -- D7
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1000") => -- D8
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1001") => -- D9
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ v_txstep := "01";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when ("1010") => -- D10, set done bit
+ if s_m13_txshift_en = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9 downto 0) <= s_tran_sh(10 downto 1);
+ s_tran_done <= '1';
+ v_txstep := "10";
+ s_txdm0 <= s_tran_sh(1);
+ end if;
+ when others => -- D0
+ -- commence transmission if conditions are met
+ s_txdm0 <= '1';
+ if s_m13_txshift_en = '1' then
+ if s_trans = '1' then
+ s_tran_sh(10) <= '1';
+ s_tran_sh(9) <= s_tb8;
+ s_tran_sh(8 downto 1) <= unsigned(sbuf_i);
+ s_tran_sh(0) <= '0';
+ s_tran_done <= '0';
+ v_txstep := "01";
+ s_txdm0 <= '0';
+ end if;
+ end if;
+ end case;
+-------------------------------------------------------------------------------
+ when others =>
+ null;
+ end case;
+
+ case v_txstep is
+ when "01" =>
+ s_tran_state <= s_tran_state + conv_unsigned(1, 1);
+ when "10" =>
+ s_tran_state <= conv_unsigned(0, 4);
+ when others =>
+ null;
+ end case;
+
+ end if;
+ end if;
+ end process p_transmit;
+
+-------------------------------------------------------------------------------
+--**************************** RECEIVE ****************************************
+-- This is the finit state machine for the receive shift register
+-------------------------------------------------------------------------------
+
+ p_receive: process (clk, cen, reset)
+ variable v_rxstep : std_logic_vector(1 downto 0);
+
+ begin
+
+ if reset = '1' then
+ s_recv_state <= conv_unsigned(0,4);
+ s_recv_sh <= conv_unsigned(0,8);
+ s_recv_buf <= conv_unsigned(0,8);
+ s_recv_done <= '0';
+ s_rb8 <= '0';
+ else
+ if clk'event and clk = '1' and cen='1' then
+
+-------------------------------------------------------------------------------
+-- MODE 0
+-------------------------------------------------------------------------------
+ v_rxstep := "00";
+ case s_mode is
+ when ("00") =>
+ case s_recv_state is
+ when ("0000") => -- D0
+ -- commence reception if conditions are met
+ if s_ren = '1' and s_ri = '0' then
+ if s_m0_shift_en = '1' then
+ v_rxstep := "01";
+ s_recv_done <= '0';
+ end if;
+ end if;
+ when ("0001") => -- D1
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0010") => -- D2
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0011") => -- D3
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0100") => -- D4
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0101") => -- D5
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0110") => -- D6
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0111") => -- D6
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1000") => -- D7, set bits and store data
+ if s_m0_shift_en = '1' then
+ s_recv_sh(7) <= rxd_i;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ s_recv_done <= '1';
+ s_recv_buf(7) <= rxd_i;
+ s_recv_buf(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "10";
+ end if;
+ when others =>
+ v_rxstep := "10";
+ end case;
+
+-------------------------------------------------------------------------------
+-- MODE 1
+-------------------------------------------------------------------------------
+ when ("01") =>
+ case s_recv_state is
+ when ("0000") => -- synchronise reception
+ if s_ren = '1' and s_detect = '1' then
+ v_rxstep := "01";
+ s_recv_sh <= conv_unsigned(0,8);
+ s_recv_done <= '0';
+ end if;
+ when ("0001") => -- D0 = START BIT
+ if s_detect = '0' then
+ if s_rxd_val = '0' then
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ else -- reject false start bits
+ if s_m13_rxshift_en = '1' then
+ v_rxstep := "10";
+ end if;
+ end if;
+ end if;
+ when ("0010") => -- D1
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0011") => -- D2
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0100") => -- D3
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0101") => -- D4
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0110") => -- D5
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0111") => -- D6
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1000") => -- D7
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1001") => -- D8
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1010") => -- D9 = STOP BIT
+ -- store data and set interrupt bit if conditions are met.
+ if (s_ri = '0' and s_sm2 = '0') or
+ (s_ri = '0' and s_rxd_val = '1') then
+ --if s_m13_rxshift_en = '1' then
+ if s_rxpre_count(3 downto 0) = conv_unsigned(10,4) then -- CK, CV: changed to enter state 0 after one stopbit
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "10";
+ s_recv_done <= '1';
+ s_rb8 <= s_rxd_val;
+ s_recv_buf <= s_recv_sh(7 downto 0);
+ end if;
+ -- forget data and recommence listening for a start bit
+ else
+ if s_m13_rxshift_en = '1' then
+ v_rxstep := "10";
+ end if;
+ end if;
+ when others =>
+ v_rxstep := "10";
+ end case;
+
+-------------------------------------------------------------------------------
+-- MODE 2
+-------------------------------------------------------------------------------
+ when ("10") =>
+ case s_recv_state is
+ when ("0000") => -- synchronise reception
+ if s_ren = '1' and s_detect = '1' then
+ v_rxstep := "01";
+ s_recv_sh <= conv_unsigned(0,8);
+ s_recv_done <= '0';
+ end if;
+ when ("0001") => -- D0 = START BIT
+ if s_rxd_val = '0' then
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ else -- reject false start bits
+ if s_m2_rxshift_en = '1' then
+ v_rxstep := "10";
+ end if;
+ end if;
+ when ("0010") => -- D1
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0011") => -- D2
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0100") => -- D3
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0101") => -- D4
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0110") => -- D5
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0111") => -- D6
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1000") => -- D7
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1001") => -- D8
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1010") => -- D9
+ -- store data and set interrupt bit if conditions are met.
+ if (s_ri = '0' and s_sm2 = '0') or
+ (s_ri = '0' and s_rxd_val = '1') then
+ if s_m2_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ s_recv_done <= '1';
+ s_rb8 <= s_rxd_val;
+ s_recv_buf <= s_recv_sh(7 downto 0);
+ end if;
+ end if;
+ -- forget data
+ if s_m2_rxshift_en = '1' then
+ v_rxstep := "01";
+ end if;
+ when ("1011") => -- D10 STOP BIT
+ -- recommence listening for a start bit
+ if s_m2_rxshift_en = '1' then
+ -- s_recv_state <= conv_unsigned(0,4);
+ v_rxstep := "10";
+ end if;
+ when others =>
+ -- s_recv_state <= conv_unsigned(0,4);
+ v_rxstep := "10";
+ end case;
+
+-------------------------------------------------------------------------------
+-- MODE 3
+-------------------------------------------------------------------------------
+ when ("11") =>
+ case s_recv_state is
+ when ("0000") => -- synchronise reception
+ if s_ren = '1' and s_detect = '1' then
+ v_rxstep := "01";
+ s_recv_sh <= conv_unsigned(0,8);
+ s_recv_done <= '0';
+ end if;
+ when ("0001") => -- D0 = START BIT
+ if s_detect = '0' then
+ if s_rxd_val = '0' then
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ else -- reject false start bits
+ if s_m13_rxshift_en = '1' then
+ v_rxstep := "10";
+ end if;
+ end if;
+ end if;
+ when ("0010") => -- D1
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0011") => -- D2
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0100") => -- D3
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0101") => -- D4
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0110") => -- D5
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("0111") => -- D6
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1000") => -- D7
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1001") => -- D8
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ v_rxstep := "01";
+ end if;
+ when ("1010") => -- D9
+ -- store data and set interrupt bit if conditions are met.
+ if (s_ri = '0' and s_sm2 = '0') or
+ (s_ri = '0' and s_rxd_val = '1') then
+ if s_m13_rxshift_en = '1' then
+ s_recv_sh(7) <= s_rxd_val;
+ s_recv_sh(6 downto 0) <= s_recv_sh(7 downto 1);
+ s_recv_done <= '1';
+ s_rb8 <= s_rxd_val;
+ s_recv_buf <= s_recv_sh(7 downto 0);
+ end if;
+ end if;
+ -- forget data
+ if s_m13_rxshift_en = '1' then
+ v_rxstep := "01";
+ end if;
+ when ("1011") => -- D10 STOP BIT
+ -- recommence listening for a start bit
+ if s_m13_rxshift_en = '1' then
+ v_rxstep := "10";
+ end if;
+ when others =>
+ v_rxstep := "10";
+ end case;
+ when others =>
+ null;
+ end case;
+
+ case v_rxstep is
+ when "01" =>
+ s_recv_state <= s_recv_state + conv_unsigned(1,1);
+ when "10" =>
+ s_recv_state <= conv_unsigned(0,4);
+ when others =>
+ null;
+ end case;
+
+ end if;
+ end if;
+
+
+ end process p_receive;
+
+
+end rtl;
diff --git a/testsuite/synth/issue2273/mc8051_siu_rtl_cfg.vhd b/testsuite/synth/issue2273/mc8051_siu_rtl_cfg.vhd
new file mode 100644
index 000000000..4f8b1def7
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_siu_rtl_cfg.vhd
@@ -0,0 +1,71 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: mc8051_siu_rtl_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:45 $
+--
+--
+-- Description: Serial interface unit for the mc8051 microcontroller.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration mc8051_siu_rtl_cfg of mc8051_siu is
+
+ for rtl
+
+ end for;
+
+end mc8051_siu_rtl_cfg;
diff --git a/testsuite/synth/issue2273/mc8051_tmrctr_.vhd b/testsuite/synth/issue2273/mc8051_tmrctr_.vhd
new file mode 100644
index 000000000..7f3b94af0
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_tmrctr_.vhd
@@ -0,0 +1,96 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: mc8051_tmrctr_.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:45 $
+--
+--
+-- Description: Timer/Counter unit of the mc8051 microcontroller.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_arith.all;
+
+-----------------------------ENTITY DECLARATION--------------------------------
+
+entity mc8051_tmrctr is
+
+ port (clk : in std_logic; --< system clock
+ cen : in std_logic; --< system clock enable
+ reset : in std_logic; --< system reset
+ int0_i : in std_logic; --< interrupt 0
+ int1_i : in std_logic; --< interrupt 1
+ t0_i : in std_logic; --< external clock for
+ -- timer/counter0
+ t1_i : in std_logic; --< external clock for
+ -- timer/counter1
+ tmod_i : in std_logic_vector(7 downto 0); --< from SFR register
+ tcon_tr0_i : in std_logic; --< timer run 0
+ tcon_tr1_i : in std_logic; --< timer run 1
+ reload_i : in std_logic_vector(7 downto 0); --< to load counter
+ wt_en_i : in std_logic; --< indicates reload
+ wt_i : in std_logic_vector(1 downto 0); --< reload which reg.
+ th0_o : out std_logic_vector(7 downto 0); --< contents of th0
+ tl0_o : out std_logic_vector(7 downto 0); --< contents of tl0
+ th1_o : out std_logic_vector(7 downto 0); --< contents of th1
+ tl1_o : out std_logic_vector(7 downto 0); --< contents of tl1
+ tf0_o : out std_logic; --< interrupt flag 0
+ tf1_o : out std_logic); --< interrupt flag 1
+
+end mc8051_tmrctr;
+
diff --git a/testsuite/synth/issue2273/mc8051_tmrctr_rtl.vhd b/testsuite/synth/issue2273/mc8051_tmrctr_rtl.vhd
new file mode 100644
index 000000000..43ed380b9
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_tmrctr_rtl.vhd
@@ -0,0 +1,766 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: mc8051_tmrctr_rtl.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.9 $
+--
+-- Date of Latest Version: $Date: 2006-09-07 09:43:21 $
+--
+--
+-- Description: Timer/Counter unit of the mc8051 microcontroller.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+architecture rtl of mc8051_tmrctr is
+
+ signal s_pre_count : unsigned(3 downto 0); -- these two signals provide
+ signal s_count_enable : std_logic; -- a clock enable signal which
+ -- masks out every twelfth
+ -- rising edge of clk
+
+ signal s_count0 : unsigned(15 downto 0); -- count for tmr/ctr0
+ signal s_countl0 : unsigned(7 downto 0); -- count register for tmr/ctr0
+ signal s_counth0 : unsigned(7 downto 0); -- count register for tmr/ctr0
+ signal s_count1 : unsigned(15 downto 0); -- count for tmr/ctr1
+ signal s_countl1 : unsigned(7 downto 0); -- count register for tmr/ctr1
+ signal s_counth1 : unsigned(7 downto 0); -- count register for tmr/ctr1
+ signal s_gate0 : std_logic; -- gate bit for tmr/ctr 0
+ signal s_gate1 : std_logic; -- gate bit for tmr/ctr 1
+ signal s_c_t0 : std_logic; -- tmr/ctr 0 is timer if 0
+ signal s_c_t1 : std_logic; -- tmr/ctr 1 is timer if 0
+ signal s_tmr_ctr0_en : std_logic; -- starts tmr/ctr 0 if 1
+ signal s_tmr_ctr1_en : std_logic; -- starts tmr/ctr 1 if 1
+ signal s_mode0 : unsigned(1 downto 0); -- mode of tmr/ctr 0
+ signal s_mode1 : unsigned(1 downto 0); -- mode of tmr/ctr 1
+ signal s_tf0 : std_logic; -- overflow flag of tmr/ctr 0
+ signal s_tf1 : std_logic; -- overflow flag of tmr/ctr 1
+ signal s_t0ff0 : std_logic; -- flipflop for edge dedection
+ signal s_t0ff1 : std_logic; -- flipflop for edge dedection
+ signal s_t0ff2 : std_logic; -- flipflop for edge dedection
+ signal s_t1ff0 : std_logic; -- flipflop for edge dedection
+ signal s_t1ff1 : std_logic; -- flipflop for edge dedection
+ signal s_t1ff2 : std_logic; -- flipflop for edge dedection
+ signal s_ext_edge0 : std_logic; -- 1 if external edge dedected
+ signal s_ext_edge1 : std_logic; -- 1 if external edge dedected
+ signal s_int0_sync : std_logic_vector(1 downto 0); -- sync int0 input
+ signal s_int1_sync : std_logic_vector(1 downto 0); -- sync int1 input
+
+
+begin -- architecture rtl
+
+ -- The names of the following signals make the code more readable.
+ s_gate0 <= tmod_i(3);
+ s_c_t0 <= tmod_i(2);
+ s_mode0(1) <= tmod_i(1);
+ s_mode0(0) <= tmod_i(0);
+
+ s_gate1 <= tmod_i(7);
+ s_c_t1 <= tmod_i(6);
+ s_mode1(1) <= tmod_i(5);
+ s_mode1(0) <= tmod_i(4);
+
+ -- These two signals start the corresponding timer/counter if they are 1.
+ s_tmr_ctr0_en <= tcon_tr0_i and (not(s_gate0) or s_int0_sync(1));
+ s_tmr_ctr1_en <= (not(s_gate1) or s_int1_sync(1)) when
+ s_mode0 = conv_unsigned(3,2) else
+ tcon_tr1_i and (not(s_gate1) or s_int1_sync(1));
+
+ -- The outputs of this unit are the two timer overflow flags, which are read
+ -- by the control unit and the two 16 bit count registers to enable read
+ -- access.
+ tf0_o <= s_tf0;
+ tf1_o <= s_tf1;
+ th0_o <= std_logic_vector(s_count0(15 downto 8));
+ tl0_o <= std_logic_vector(s_count0(7 downto 0));
+ th1_o <= std_logic_vector(s_count1(15 downto 8));
+ tl1_o <= std_logic_vector(s_count1(7 downto 0));
+
+-------------------------------------------------------------------------------
+ -- The register s_pre_count is driven with the system clock. So a
+ -- good enable signal (which is stable when clk has its rising edge) can be
+ -- derived to mask out every twelfth pulse of clk. Also synchronize the
+ -- interrupt inputs here.
+
+ s_count_enable <= '1' when s_pre_count = conv_unsigned(11,4) else '0';
+
+ p_divide_clk: process (clk, cen, reset)
+
+ begin
+
+ if reset = '1' then
+ s_pre_count <= conv_unsigned(0,4);
+ s_int0_sync <= "00";
+ s_int1_sync <= "00";
+ else
+ if clk'event and clk='1' and cen='1' then
+ s_pre_count <= s_pre_count + conv_unsigned(1,1);
+ if s_pre_count = conv_unsigned(11,4) then
+ s_pre_count <= conv_unsigned(0,4);
+ end if;
+ s_int0_sync(0) <= int0_i;
+ s_int0_sync(1) <= s_int0_sync(0);
+ s_int1_sync(0) <= int1_i;
+ s_int1_sync(1) <= s_int1_sync(0);
+ end if;
+ end if;
+
+ end process p_divide_clk;
+
+-------------------------------------------------------------------------------
+ -- The two flip flops are updated every second clock period.
+ -- If a falling edge
+ -- on the port t0_i is dedected the signal s_ext_edge0 is set to 1 and with
+ -- the next rising edge of clk the counter0 is incremented.
+ -- The same function is realised for counter1.
+ s_ext_edge0 <= '1' when (s_t0ff1 = '0' and s_t0ff2 = '1') else '0';
+
+ p_sample_t0: process (clk, cen, reset)
+
+ begin
+
+ if reset = '1' then
+ s_t0ff0 <= '0';
+ s_t0ff1 <= '0';
+ s_t0ff2 <= '0';
+ else
+
+ if clk'event and clk = '1' and cen='1' then
+ if s_pre_count = conv_unsigned(6,3) then
+ if s_c_t0 = '1' then
+ s_t0ff0 <= t0_i;
+ s_t0ff1 <= s_t0ff0;
+ s_t0ff2 <= s_t0ff1;
+ end if;
+ end if;
+ end if;
+ end if;
+
+ end process p_sample_t0;
+
+ s_ext_edge1 <= '1' when (s_t1ff1 = '0' and s_t1ff2 = '1') else '0';
+
+ p_sample_t1: process (clk, cen, reset)
+
+ begin
+
+ if reset = '1' then
+ s_t1ff0 <= '0';
+ s_t1ff1 <= '0';
+ s_t1ff2 <= '0';
+ else
+ if clk'event and clk = '1' and cen='1' then
+ if s_pre_count = conv_unsigned(6,3) then
+ if s_c_t1 = '1' then
+ s_t1ff0 <= t1_i;
+ s_t1ff1 <= s_t1ff0;
+ s_t1ff2 <= s_t1ff1;
+ end if;
+ end if;
+ end if;
+ end if;
+
+ end process p_sample_t1;
+
+------------------------------------------------------------------------------
+--+++++++++++++++++++++ TIMER / COUNTER 0 ++++++++++++++++++++++++++++++--
+------------------------------------------------------------------------------
+-- This is timer/counter0. It is built around the 16 bit count register
+-- s_count0 and realises its four operating modes
+------------------------------------------------------------------------------
+ s_count0(15 downto 8) <= s_counth0;
+ s_count0(7 downto 0) <= s_countl0;
+ s_count1(15 downto 8) <= s_counth1;
+ s_count1(7 downto 0) <= s_countl1;
+
+ p_tmr_ctr: process (clk, cen, reset)
+
+ begin
+
+ if reset = '1' then -- perform asynchronous reset
+
+ s_countl0 <= conv_unsigned(0,8);
+ s_counth0 <= conv_unsigned(0,8);
+ s_countl1 <= conv_unsigned(0,8);
+ s_counth1 <= conv_unsigned(0,8);
+ s_tf1 <= '0';
+ s_tf0 <= '0';
+
+ else
+
+ if clk'event and clk = '1' and cen='1' then
+ s_tf1 <= '0';
+ s_tf0 <= '0';
+
+-------------------------------------------------------------------------------
+-- operating mode 0 (13 bit timer/counter)
+-------------------------------------------------------------------------------
+ case s_mode0 is
+ when "00" =>
+
+ -- This section generates the timer/counter overflow flag0
+ if s_tmr_ctr0_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t0 = '0' or (s_ext_edge0 = '1' and s_c_t0 = '1') then
+ if s_count0 = conv_unsigned(65311,16) then
+ s_tf0 <= '1';
+ else
+ s_tf0 <= '0';
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the low byte register of tmr/ctr0
+ if wt_i = "00" and wt_en_i = '1' then
+ s_countl0 <= unsigned(reload_i);
+ else
+ if s_tmr_ctr0_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t0 = '0' then
+ if s_countl0 = conv_unsigned(31,8) then
+ s_countl0 <= conv_unsigned(0,8);
+ else
+ s_countl0 <= s_countl0 + conv_unsigned(1,1);
+ end if;
+ else
+ if s_ext_edge0 = '1' then
+ if s_countl0 = conv_unsigned(31,8) then
+ s_countl0 <= conv_unsigned(0,8);
+ else
+ s_countl0 <= s_countl0 + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the high byte register of tmr/ctr0
+ if wt_i = "10" and wt_en_i = '1' then
+ s_counth0 <= unsigned(reload_i);
+ else
+ if s_tmr_ctr0_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t0 = '0' then
+ if s_count0 = conv_unsigned(65311,16) then
+ s_counth0 <= conv_unsigned(0,8);
+ else
+ if s_countl0 = conv_unsigned(31,8) then
+ s_counth0 <= s_counth0 + conv_unsigned(1,1);
+ end if;
+ end if;
+ else
+ if s_ext_edge0 = '1' then
+ if s_count0 = conv_unsigned(65311,16) then
+ s_counth0 <= conv_unsigned(0,8);
+ else
+ if s_countl0 = conv_unsigned(31,8) then
+ s_counth0 <= s_counth0 + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+-------------------------------------------------------------------------------
+-- operating mode 1 (16 bit timer/counter)
+-------------------------------------------------------------------------------
+
+ when "01" =>
+
+ -- This section generates the timer/counter overflow flag0
+ if s_tmr_ctr0_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t0 = '0' or (s_ext_edge0 = '1' and s_c_t0 = '1') then
+ if s_count0 = conv_unsigned(65535,16) then
+ s_tf0 <= '1';
+ else
+ s_tf0 <= '0';
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the low byte register of tmr/ctr0
+ if wt_i = "00" and wt_en_i = '1' then
+ s_countl0 <= unsigned(reload_i);
+ else
+ if s_tmr_ctr0_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t0 = '0' then
+ if s_count0 = conv_unsigned(65535,16) then
+ s_countl0 <= conv_unsigned(0,8);
+ else
+ s_countl0 <= s_countl0 + conv_unsigned(1,1);
+ end if;
+ else
+ if s_ext_edge0 = '1' then
+ if s_count0 = conv_unsigned(65535,16) then
+ s_countl0 <= conv_unsigned(0,8);
+ else
+ s_countl0 <= s_countl0 + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the high byte register of tmr/ctr0
+ if wt_i = "10" and wt_en_i = '1' then
+ s_counth0 <= unsigned(reload_i);
+ else
+ if s_tmr_ctr0_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t0 = '0' then
+ if s_count0 = conv_unsigned(65535,16) then
+ s_counth0 <= conv_unsigned(0,8);
+ else
+ if s_countl0 = conv_unsigned(255,8) then
+ s_counth0 <= s_counth0 + conv_unsigned(1,1);
+ end if;
+ end if;
+ else
+ if s_ext_edge0 = '1' then
+ if s_count0 = conv_unsigned(65535,16) then
+ s_counth0 <= conv_unsigned(0,8);
+ else
+ if s_countl0 = conv_unsigned(255,8) then
+ s_counth0 <= s_counth0 + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+
+
+-------------------------------------------------------------------------------
+-- operating mode 2 (8 bit timer/counter, autoreloaded from high byte register)
+-------------------------------------------------------------------------------
+
+ when "10" =>
+
+ -- This section generates the timer/counter overflow flag0
+ if s_tmr_ctr0_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t0 = '0' or (s_ext_edge0 = '1' and s_c_t0 = '1') then
+ if s_count0(7 downto 0) = conv_unsigned(255,16) then
+ s_tf0 <= '1';
+ else
+ s_tf0 <= '0';
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the low byte register of tmr/ctr0
+ if wt_i = "00" and wt_en_i = '1' then
+ s_countl0 <= unsigned(reload_i);
+ else
+ if s_tmr_ctr0_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t0 = '0' then
+ if s_countl0 = conv_unsigned(255,8) then
+ s_countl0 <= s_counth0;
+ else
+ s_countl0 <= s_countl0 + conv_unsigned(1,1);
+ end if;
+ else
+ if s_ext_edge0 = '1' then
+ if s_countl0 = conv_unsigned(255,8) then
+ s_countl0 <= s_counth0;
+ else
+ s_countl0 <= s_countl0 + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the high byte register of tmr/ctr0
+ if wt_i = "10" and wt_en_i = '1' then
+ s_counth0 <= unsigned(reload_i);
+ end if;
+
+-------------------------------------------------------------------------------
+-- operating mode 3 (One 8 bit timer/counter and one 8 bit timer)
+-------------------------------------------------------------------------------
+
+ when "11" =>
+
+ -- This section generates the timer/counter overflow flag0
+ if s_tmr_ctr0_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t0 = '0' or (s_ext_edge0 = '1' and s_c_t0 = '1') then
+ if s_count0(7 downto 0) = conv_unsigned(255,16) then
+ s_tf0 <= '1';
+ else
+ s_tf0 <= '0';
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the low byte register of tmr/ctr0
+ if wt_i = "00" and wt_en_i = '1' then
+ s_countl0 <= unsigned(reload_i);
+ else
+ if s_tmr_ctr0_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t0 = '0' then
+ if s_countl0 = conv_unsigned(255,8) then
+ s_countl0 <= conv_unsigned(0,8);
+ else
+ s_countl0 <= s_countl0 + conv_unsigned(1,1);
+ end if;
+ else
+ if s_ext_edge0 = '1' then
+ if s_countl0 = conv_unsigned(255,8) then
+ s_countl0 <= conv_unsigned(0,8);
+ else
+ s_countl0 <= s_countl0 + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the timer/counter overflow flag1
+ if tcon_tr1_i = '1' then
+ if s_count_enable = '1' then
+ if s_count0(15 downto 8) = conv_unsigned(255,8) then
+ s_tf1 <= '1';
+ else
+ s_tf1 <= '0';
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the high byte register of tmr/ctr0
+ if wt_i = "10" and wt_en_i = '1' then
+ s_counth0 <= unsigned(reload_i);
+ else
+ if tcon_tr1_i = '1' then
+ if s_count_enable = '1' then
+ if s_counth0 = conv_unsigned(255,8) then
+ s_counth0 <= conv_unsigned(0,8);
+ else
+ s_counth0 <= s_counth0 + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+ end if;
+
+ when others => null;
+ end case;
+
+------------------------------------------------------------------------------
+--+++++++++++++++++ END OF TIMER / COUNTER 0 +++++++++++++++++++++++++++--
+------------------------------------------------------------------------------
+
+
+------------------------------------------------------------------------------
+--+++++++++++++++++++++ TIMER / COUNTER 1 ++++++++++++++++++++++++++++++--
+------------------------------------------------------------------------------
+-- This is timer/counter1. It is built around the 16 bit count register
+-- s_count1 and realises its four operating modes
+------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- operating mode 0 (13 bit timer/counter)
+-------------------------------------------------------------------------------
+ case s_mode1 is
+ when "00" =>
+
+ -- This section generates the timer/counter overflow flag1
+ if s_tmr_ctr1_en = '1' then
+ if s_count_enable = '1' then
+ if s_mode0 = conv_unsigned(1,2) or
+ s_mode0 = conv_unsigned(0,2) or
+ s_mode0 = conv_unsigned(2,2) then
+ if s_c_t1 = '0' or (s_ext_edge1 = '1' and s_c_t1 = '1') then
+ if s_count1 = conv_unsigned(65311,16) then
+ s_tf1 <= '1';
+ else
+ s_tf1 <= '0';
+ end if;
+ end if;
+ else
+ null;
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the low byte register of tmr/ctr1
+ if wt_i = "01" and wt_en_i = '1' then
+ s_countl1 <= unsigned(reload_i);
+ else
+ if s_tmr_ctr1_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t1 = '0' then
+ if s_countl1 = conv_unsigned(31,8) then
+ s_countl1 <= conv_unsigned(0,8);
+ else
+ s_countl1 <= s_countl1 + conv_unsigned(1,1);
+ end if;
+ else
+ if s_ext_edge1 = '1' then
+ if s_countl1 = conv_unsigned(31,8) then
+ s_countl1 <= conv_unsigned(0,8);
+ else
+ s_countl1 <= s_countl1 + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the high byte register of tmr/ctr1
+ if wt_i = "11" and wt_en_i = '1' then
+ s_counth1 <= unsigned(reload_i);
+ else
+ if s_tmr_ctr1_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t1 = '0' then
+ if s_count1 = conv_unsigned(65311,16) then
+ s_counth1 <= conv_unsigned(0,8);
+ else
+ if s_countl1 = conv_unsigned(31,8) then
+ s_counth1 <= s_counth1 + conv_unsigned(1,1);
+ end if;
+ end if;
+ else
+ if s_ext_edge1 = '1' then
+ if s_count1 = conv_unsigned(65311,16) then
+ s_counth1 <= conv_unsigned(0,8);
+ else
+ if s_countl1 = conv_unsigned(31,8) then
+ s_counth1 <= s_counth1 + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+-------------------------------------------------------------------------------
+-- operating mode 1 (16 bit timer/counter)
+-------------------------------------------------------------------------------
+
+ when "01" =>
+
+ -- This section generates the timer/counter overflow flag1
+ if s_tmr_ctr1_en = '1' then
+ if s_count_enable = '1' then
+ if s_mode0 = conv_unsigned(1,2) or
+ s_mode0 = conv_unsigned(0,2) or
+ s_mode0 = conv_unsigned(2,2) then
+ if s_c_t1 = '0' or (s_ext_edge1 = '1' and s_c_t1 = '1') then
+ if s_count1 = conv_unsigned(65535,16) then
+ s_tf1 <= '1';
+ else
+ s_tf1 <= '0';
+ end if;
+ end if;
+ else
+ null;
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the low byte register of tmr/ctr1
+ if wt_i = "01" and wt_en_i = '1' then
+ s_countl1 <= unsigned(reload_i);
+ else
+ if s_tmr_ctr1_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t1 = '0' then
+ if s_count1 = conv_unsigned(65535,16) then
+ s_countl1 <= conv_unsigned(0,8);
+ else
+ s_countl1 <= s_countl1 + conv_unsigned(1,1);
+ end if;
+ else
+ if s_ext_edge1 = '1' then
+ if s_count1 = conv_unsigned(65535,16) then
+ s_countl1 <= conv_unsigned(0,8);
+ else
+ s_countl1 <= s_countl1 + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the high byte register of tmr/ctr1
+ if wt_i = "11" and wt_en_i = '1' then
+ s_counth1 <= unsigned(reload_i);
+ else
+ if s_tmr_ctr1_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t1 = '0' then
+ if s_count1 = conv_unsigned(65535,16) then
+ s_counth1 <= conv_unsigned(0,8);
+ else
+ if s_countl1 = conv_unsigned(255,8) then
+ s_counth1 <= s_counth1 + conv_unsigned(1,1);
+ end if;
+ end if;
+ else
+ if s_ext_edge1 = '1' then
+ if s_count1 = conv_unsigned(65535,16) then
+ s_counth1 <= conv_unsigned(0,8);
+ else
+ if s_countl1 = conv_unsigned(255,8) then
+ s_counth1 <= s_counth1 + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+
+-------------------------------------------------------------------------------
+-- operating mode 2 (8 bit timer/counter, auto reloaded)
+-------------------------------------------------------------------------------
+
+ when "10" =>
+
+ -- This section generates the timer/counter overflow flag1
+ if s_tmr_ctr1_en = '1' then
+ if s_count_enable = '1' then
+ if s_mode0 = conv_unsigned(1,2) or
+ s_mode0 = conv_unsigned(0,2) or
+ s_mode0 = conv_unsigned(2,2) then
+ if s_c_t1 = '0' or (s_ext_edge1 = '1' and s_c_t1 = '1') then
+ if s_count1(7 downto 0) = conv_unsigned(255,16) then
+ s_tf1 <= '1';
+ else
+ s_tf1 <= '0';
+ end if;
+ end if;
+ else
+ null;
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the low byte register of tmr/ctr1
+ if wt_i = "01" and wt_en_i = '1' then
+ s_countl1 <= unsigned(reload_i);
+ else
+ if s_tmr_ctr1_en = '1' then
+ if s_count_enable = '1' then
+ if s_c_t1 = '0' then
+ if s_countl1 = conv_unsigned(255,8) then
+ s_countl1 <= s_counth1;
+ else
+ s_countl1 <= s_countl1 + conv_unsigned(1,1);
+ end if;
+ else
+ if s_ext_edge1 = '1' then
+ if s_countl1 = conv_unsigned(255,8) then
+ s_countl1 <= s_counth1;
+ else
+ s_countl1 <= s_countl1 + conv_unsigned(1,1);
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- This section generates the high byte register of tmr/ctr1
+ if wt_i = "11" and wt_en_i = '1' then
+ s_counth1 <= unsigned(reload_i);
+ end if;
+
+-------------------------------------------------------------------------------
+-- operating mode 3 (One 8 bit timer/counter and one 8 bit timer)
+-------------------------------------------------------------------------------
+
+ when "11" =>
+
+ -- This section generates the low byte register of tmr/ctr1
+ if wt_i = "01" and wt_en_i = '1' then
+ s_countl1 <= unsigned(reload_i);
+ end if;
+
+ -- This section generates the high byte register of tmr/ctr1
+ if wt_i = "11" and wt_en_i = '1' then
+ s_counth1 <= unsigned(reload_i);
+ end if;
+
+ when others => null;
+ end case;
+------------------------------------------------------------------------------
+--+++++++++++++++++ END OF TIMER / COUNTER 1 +++++++++++++++++++++++++++--
+------------------------------------------------------------------------------
+
+ end if;
+ end if;
+
+ end process p_tmr_ctr;
+
+
+end rtl;
+
diff --git a/testsuite/synth/issue2273/mc8051_tmrctr_rtl_cfg.vhd b/testsuite/synth/issue2273/mc8051_tmrctr_rtl_cfg.vhd
new file mode 100644
index 000000000..2c3d84271
--- /dev/null
+++ b/testsuite/synth/issue2273/mc8051_tmrctr_rtl_cfg.vhd
@@ -0,0 +1,71 @@
+-------------------------------------------------------------------------------
+-- --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- XX XX X X X X X X X XX --
+-- X X X X X X X X X X X X --
+-- X X X X X X X X X X X X --
+-- X X X X XXXXXX X X XXXXXX X --
+-- X X X X X X X X X --
+-- X X X X X X X X X --
+-- X X X X X X X X X X --
+-- X X XXXXXX XXXXXX XXXXXX XXXXXX X --
+-- --
+-- --
+-- O R E G A N O S Y S T E M S --
+-- --
+-- Design & Consulting --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- Web: http://www.oregano.at/ --
+-- --
+-- Contact: mc8051@oregano.at --
+-- --
+-------------------------------------------------------------------------------
+-- --
+-- MC8051 - VHDL 8051 Microcontroller IP Core --
+-- Copyright (C) 2001 OREGANO SYSTEMS --
+-- --
+-- This library is free software; you can redistribute it and/or --
+-- modify it under the terms of the GNU Lesser General Public --
+-- License as published by the Free Software Foundation; either --
+-- version 2.1 of the License, or (at your option) any later version. --
+-- --
+-- This library 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 --
+-- Lesser General Public License for more details. --
+-- --
+-- Full details of the license can be found in the file LGPL.TXT. --
+-- --
+-- You should have received a copy of the GNU Lesser General Public --
+-- License along with this library; if not, write to the Free Software --
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
+-- --
+-------------------------------------------------------------------------------
+--
+--
+-- Author: Roland Höller
+--
+-- Filename: mc8051_tmrctr_rtl_cfg.vhd
+--
+-- Date of Creation: Mon Aug 9 12:14:48 1999
+--
+-- Version: $Revision: 1.4 $
+--
+-- Date of Latest Version: $Date: 2002-01-07 12:17:45 $
+--
+--
+-- Description: Timer/Counter unit of the mc8051 microcontroller.
+--
+--
+--
+--
+-------------------------------------------------------------------------------
+configuration mc8051_tmrctr_rtl_cfg of mc8051_tmrctr is
+
+ for rtl
+
+ end for;
+
+end mc8051_tmrctr_rtl_cfg;
diff --git a/testsuite/synth/issue2273/testsuite.sh b/testsuite/synth/issue2273/testsuite.sh
new file mode 100755
index 000000000..ad242b83f
--- /dev/null
+++ b/testsuite/synth/issue2273/testsuite.sh
@@ -0,0 +1,7 @@
+#! /bin/sh
+
+. ../../testenv.sh
+
+synth -fsynopsys --out=verilog @mc8051.f -e mc8051_core > mc8051.v
+
+echo "Test successful"