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.
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.