diff options
author | Tristan Gingold <tgingold@free.fr> | 2022-12-18 08:35:43 +0100 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2022-12-18 08:36:15 +0100 |
commit | b4f09236ad974a133318d17a8487b36ebc35a78c (patch) | |
tree | a2d61d7039219d334b60d61946705c2d63de8264 | |
parent | 36c276363fa35f6856bbd44e7a37e712aaab2a1e (diff) | |
download | ghdl-b4f09236ad974a133318d17a8487b36ebc35a78c.tar.gz ghdl-b4f09236ad974a133318d17a8487b36ebc35a78c.tar.bz2 ghdl-b4f09236ad974a133318d17a8487b36ebc35a78c.zip |
testsuite/synth: add a test for #2273
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" |