Search code examples
simulationvhdlxilinx

Why am I getting "Entity port d does not match with type unsigned of component portParsing..." when I try to simulate this VHDL?


The full error message is:

ERROR:HDLCompiler:377 - "C:/Users/einar/Documents/Xilinx/ISE/Projects/EDA385/scale_clock_tb.vhd" Line 17: Entity port d does not match with type unsigned of component port

I'm using ISE web pack and I have implemented the top module, the top module is scale_clock.

Also, it simulates just fine when I do behavioral simulation. But for post-map or post-route I get the error message above.

This is the code for the component:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

-----------------------------------------
-- scale_clock entity declaration --
-----------------------------------------
ENTITY scale_clock IS
  GENERIC (n_bits : INTEGER := 10);
  PORT
  (
    clk_i  : IN  STD_LOGIC;
    load   : IN  STD_LOGIC;
    d      : IN  UNSIGNED (n_bits-1 DOWNTO 0) := (OTHERS => '0');
    clk_o  : OUT STD_LOGIC 
  );
END scale_clock;

----------------------------------------------
-- scale_clock architecture definition --
----------------------------------------------
ARCHITECTURE behavioral OF scale_clock IS
  SIGNAL new_clk : STD_LOGIC := '0';

BEGIN
  clk_o <= new_clk;

  clk_gen: PROCESS(clk_i, load, d) -- Should load and d be in the stvty list? --
    VARIABLE cnt : UNSIGNED (n_bits-1 DOWNTO 0) := (0 => '1', OTHERS => '0');
    VARIABLE top : UNSIGNED (n_bits-1 DOWNTO 0) := (OTHERS => '0');
  BEGIN
    IF (rising_edge(clk_i)) THEN
      IF (load = '1') THEN
      -- Syncrounous load of prescaler value. --
        top     := d;
        cnt     := (0 => '1', OTHERS => '0');
        new_clk <= '0';
      ELSIF (cnt = top) THEN
        cnt     := (0 => '1', OTHERS => '0');
        new_clk <= NOT new_clk;
      ELSE
      -- Count up. --  
        cnt := cnt + 1;
      END IF;
    END IF;  
  END PROCESS;
END ARCHITECTURE;

And this is the testbench:

-- TestBench Template 
LIBRARY ieee;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

ENTITY scale_clock_testbench IS
END scale_clock_testbench ;

ARCHITECTURE behavior OF scale_clock_testbench  IS 

-- Component Declaration
  COMPONENT scale_clock
  PORT
  (
    clk_i : IN STD_LOGIC;
    load  : IN STD_LOGIC;       
    d     : IN UNSIGNED (9 DOWNTO 0) := (OTHERS => '0');
    clk_o : OUT STD_LOGIC
  );
  END COMPONENT;

  SIGNAL  clk_i :  STD_LOGIC := '0';
  SIGNAL  load  :  STD_LOGIC := '0';
  SIGNAL  d     :  UNSIGNED (9 DOWNTO 0) := (OTHERS => '0');
  SIGNAL  clk_o :  STD_LOGIC := '0';

  CONSTANT CLK_PERIOD : TIME := 10 ns;

BEGIN

-- Component Instantiation
  uut: scale_clock PORT MAP
  (
    clk_i =>    clk_i,
    load  =>    load,
    d     =>    d,
    clk_o =>    clk_o
  );

  clk_process : PROCESS
  BEGIN
    clk_i   <=    '0';
    WAIT FOR CLK_PERIOD/2;
    clk_i   <=    '1';
    WAIT FOR CLK_PERIOD/2;
  END PROCESS;



--  Test Bench Statements
   tb : PROCESS
   BEGIN

      WAIT FOR 100 ns; -- wait until global set/reset completes

      -- Add user defined stimulus here

      WAIT FOR CLK_PERIOD * 3;
      d     <=  ("0100101100"); -- decimal 300 in binary --
      load  <= '1';
      WAIT FOR CLK_PERIOD * 1;
      load  <= '0';


      wait; -- will wait forever
   END PROCESS tb;
--  End Test Bench 

END;

I'm new to VHDL but to me they seem to match just fine. Please advice.


Solution

  • The problem is (almost) correctly identified in Tsukuyo's answer. Namely that the OUTPUT from synthesis (and P&R) contains std_logic[_vector] everywhere, and if you try to simulate these files, your testbench connections need to match their types.

    Xilinx tools try to force a terrible solution on you, namely to use std_logic[_vector] everywhere instead of making the design and testbench actually reflect the design's intent. To the extent that if you let it auto-generate a testbench for a module, it will "helpfully" convert all your port types (often incorrectly if you use enumerations or records!) into std_logic[_vector].

    A better solution (IMO) is to write both your modules and testbench the way they ought to be - namely at the highest level you can (instead of wasting time messing around at low level). Not only unsigned, but enumerations, integers, booleans and records are synthesisable.

    Then (if you need to do a post-route simulation) write a simple wrapper around the auto-generated std_logic version, which converts all its ports to the correct types, and instantiate that wrapper in your testbench.