I keep getting an error that says:
line 25: type error near num_values ; current type unsigned; expected
type unsigned.
It is already the type that is supposed to be, and I think it is same in bit length and declared alright, what am I doing wrong here?
The code is about implementation of fifo queue structure.
<Queue.vhd>
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Queue is
port (
-- clock
clk: in std_logic;
-- input
push: in std_logic;
push_data: in std_logic_vector(31 downto 0);
pop: in std_logic;
-- output
pop_data: out std_logic_vector(31 downto 0);
num_values: out unsigned(31 downto 0)
);
end entity;
architecture Behavioral of Queue is
type items is array(0 to 31) of std_logic_vector(31 downto 0);
signal manager : items := (others => (others => '0'));
signal push_idx, pop_idx : integer := 0;
begin
process(clk) is
variable howmany : integer := 0;
begin
if rising_edge(clk) then
if (push = '1') then
manager(push_idx) <= push_data;
push_idx <= push_idx + 1;
howmany := howmany + 1;
end if;
if (pop = '1') then
if (howmany /= 0) then
pop_data <= manager(pop_idx);
pop_idx <= pop_idx + 1;
howmany := howmany - 1;
end if;
else
pop_data <= std_logic_vector(to_unsigned(0,pop_data'length));
end if;
if (push_idx = 31) then
push_idx <= 0;
end if;
if (pop_idx = 31) then
pop_idx <= 0;
end if;
num_values <= to_unsigned(howmany,32);
end if;
end process;
end architecture;
<QueueTb.vhd>
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity QueueTb is
end entity;
architecture sim of QueueTb is
constant ClockFrequency : integer := 100e6;
constant ClockPeriod : time := 1000ms / ClockFrequency;
signal clk : std_logic := '0';
signal push, pop : std_logic := '0';
signal num_values : unsigned(31 downto 0);
signal push_data, pop_data : std_logic_vector(31 downto 0) := (others =>'0');
begin
UUT : entity work.Queue(Behavioral)
port map(
clk => clk,
push => push,
pop => pop,
num_values => num_values, <=== this is where error occurs!
push_data => push_data,
pop_data => pop_data);
clk <= not clk after ClockPeriod / 2;
process is
begin
wait for 10 ns;
push <= '1';
push_data <= conv_std_logic_vector(123,32);
wait for 10 ns;
push_data <= conv_std_logic_vector(456,32);
wait for 10 ns;
push <= '0';
push_data <= conv_std_logic_vector(0,32);
pop <= '1';
wait for 10 ns;
pop <= '0';
push <= '1';
push_data <= conv_std_logic_vector(789,32);
wait for 10 ns;
push <= '0';
pop <= '1';
wait for 80 ns;
end process;
end architecture;
What am I doing wrong here??
In the Queue entity you are using ieee.numeric_std and in the QueueTB you are using ieee.std_logic_arith . Both define different unsigned types.
Delete std_logic_arith from the testbench as it is not a standard VHDL library and use numeric_std instead.
I'm trying to use the DDR3 memory component on my Arty board (https://reference.digilentinc.com/reference/programmable-logic/arty/reference-manual?redirect=1), which have the MT41K128M16JT-125 memory part from Micron.
The FPGA is an Artix-7 xc7a35ticsg324-1L.
I've implemented my project in VHDL, and have been using the MIG IP to generate an example project, from which I have written my own "top_level.vhd"-file.
In the "top_level.vhd"-file, the components UART_RX and UART_TX are for transmitting bytes of data using the UART, and the component mig_7series_o, have been generated by the MIG tool.
I've split my question up into smaller segments:
1) As far as I have understood it, the MIG will generate the clock signals itself, and supply me with a clock signal ui_clk, which in my code is called clk.
But when the code is synthesized, I suspect that the clock signal does not work as it should, and this leads my whole design to not work at all. Could anyone give me an idea on how to make the clock work as it should?
2) Furthermore I can't simulate my design, as I don't have a model for the RAM, but as far as I've understood it, my design would have to be in Verilog, in order to use Microns RAM simulation models, which it is not. This have lead me to the situation, that I have to synthesize the design in order to check if it works, which makes debugging it quite hard.
3) Or is there perhaps someone out there, who have a working interface on the arty board (Or a similar board), who would be so kind to share the module for interfacing with the DDR3 RAM?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity top_level is
Port (
-- Inouts
ddr3_dq : inout std_logic_vector(31 downto 0);
ddr3_dqs_p : inout std_logic_vector(3 downto 0);
ddr3_dqs_n : inout std_logic_vector(3 downto 0);
-- Outputs
ddr3_addr : out std_logic_vector(13 downto 0);
ddr3_ba : out std_logic_vector(2 downto 0);
ddr3_ras_n : out std_logic;
ddr3_cas_n : out std_logic;
ddr3_we_n : out std_logic;
ddr3_reset_n : out std_logic;
ddr3_ck_p : out std_logic_vector(0 downto 0);
ddr3_ck_n : out std_logic_vector(0 downto 0);
ddr3_cke : out std_logic_vector(0 downto 0);
ddr3_cs_n : out std_logic_vector(0 downto 0);
ddr3_dm : out std_logic_vector(3 downto 0);
ddr3_odt : out std_logic_vector(0 downto 0);
-- Inputs
-- Differential system clocks
sys_clk_p : in std_logic;
sys_clk_n : in std_logic;
-- differential iodelayctrl clk (reference clock)
clk_ref_p : in std_logic;
clk_ref_n : in std_logic;
tg_compare_error : out std_logic;
init_calib_complete : out std_logic;
-- System reset - Default polarity of sys_rst pin is Active Low.
-- System reset polarity will change based on the option
-- selected in GUI.
sys_rst : in std_logic;
led1 : out std_logic;
led2 : out std_logic;
but : in std_logic_vector(3 downto 0);
rx_bit : in std_logic;
tx_bit : out std_logic
--test_clock : in std_logic
);
end top_level;
architecture Behavioral of top_level is
component UART_RX
generic (
g_CLKS_PER_BIT : integer := 723 -- Needs to be set correctly
);
port (
i_Clk : in std_logic;
i_RX_Serial : in std_logic;
o_RX_DV : out std_logic;
o_RX_Byte : out std_logic_vector(7 downto 0)
);
end component;
component UART_TX
generic (
g_CLKS_PER_BIT : integer := 723 -- Needs to be set correctly
);
port (
i_Clk : in std_logic;
i_TX_DV : in std_logic;
i_TX_Byte : in std_logic_vector(7 downto 0);
o_TX_Active : out std_logic;
o_TX_Serial : out std_logic;
o_TX_Done : out std_logic
);
end component;
component mig_7series_0
port(
ddr3_dq : inout std_logic_vector(31 downto 0);
ddr3_dqs_p : inout std_logic_vector(3 downto 0);
ddr3_dqs_n : inout std_logic_vector(3 downto 0);
ddr3_addr : out std_logic_vector(13 downto 0);
ddr3_ba : out std_logic_vector(2 downto 0);
ddr3_ras_n : out std_logic;
ddr3_cas_n : out std_logic;
ddr3_we_n : out std_logic;
ddr3_reset_n : out std_logic;
ddr3_ck_p : out std_logic_vector(0 downto 0);
ddr3_ck_n : out std_logic_vector(0 downto 0);
ddr3_cke : out std_logic_vector(0 downto 0);
ddr3_cs_n : out std_logic_vector(0 downto 0);
ddr3_dm : out std_logic_vector(3 downto 0);
ddr3_odt : out std_logic_vector(0 downto 0);
app_addr : in std_logic_vector(27 downto 0);
app_cmd : in std_logic_vector(2 downto 0);
app_en : in std_logic;
app_wdf_data : in std_logic_vector(255 downto 0);
app_wdf_end : in std_logic;
app_wdf_mask : in std_logic_vector(31 downto 0);
app_wdf_wren : in std_logic;
app_rd_data : out std_logic_vector(255 downto 0);
app_rd_data_end : out std_logic;
app_rd_data_valid : out std_logic;
app_rdy : out std_logic;
app_wdf_rdy : out std_logic;
app_sr_req : in std_logic;
app_ref_req : in std_logic;
app_zq_req : in std_logic;
app_sr_active : out std_logic;
app_ref_ack : out std_logic;
app_zq_ack : out std_logic;
ui_clk : out std_logic;
ui_clk_sync_rst : out std_logic;
init_calib_complete : out std_logic;
-- System Clock Ports
sys_clk_p : in std_logic;
sys_clk_n : in std_logic;
-- Reference Clock Ports
clk_ref_p : in std_logic;
clk_ref_n : in std_logic;
device_temp : out std_logic_vector(11 downto 0);
sys_rst : in std_logic
);
end component mig_7series_0;
constant DATA_WIDTH : integer := 32;
constant PAYLOAD_WIDTH : integer := DATA_WIDTH;
constant nCK_PER_CLK : integer := 4;
constant ADDR_WIDTH : integer := 28;
constant APP_DATA_WIDTH : integer := 2*nCK_PER_CLK * PAYLOAD_WIDTH;
constant APP_MASK_WIDTH : integer := APP_DATA_WIDTH / 8;
signal app_addr : std_logic_vector(ADDR_WIDTH-1 downto 0);
signal init_calib_complete_i : std_logic;
signal device_temp : std_logic_vector(11 downto 0);
signal app_cmd : std_logic_vector(2 downto 0);
signal app_en : std_logic;
signal app_rdy : std_logic;
signal app_wdf_data : std_logic_vector(APP_DATA_WIDTH-1 downto 0);
signal app_wdf_end : std_logic;
signal app_ref_ack : std_logic;
signal app_zq_ack : std_logic;
signal app_wdf_wren : std_logic;
signal app_rd_data : std_logic_vector(APP_DATA_WIDTH-1 downto 0);
signal app_rd_data_end : std_logic;
signal app_rd_data_valid : std_logic;
signal app_wdf_mask : std_logic_vector(APP_MASK_WIDTH-1 downto 0);
signal app_wdf_rdy : std_logic;
signal app_sr_active : std_logic;
signal clk : std_logic;
--Mine signaler
type state_type is (reset, init, idle, prep_write, do_write, do_wait_after_write, prep_read, do_read, do_wait_after_read, clean_up, end_state);
signal state : state_type;
type init_state_type is (step1, step2, step3, step4);
signal init_state : init_state_type;
signal init_count : integer range 0 to 127 := 0;
constant c_CLKS_PER_BIT : integer := 723;
signal tx_done, rx_dv, tx_active, tx_dv, wait_for_tx_done, wait_for_but_release : STD_LOGIC;
signal tx_byte, rx_byte : STD_LOGIC_VECTOR(7 downto 0);
signal count : integer range 0 to 127 := 0;
signal data_read : std_logic_vector(31 downto 0);
signal first_init : std_logic := '1';
signal sys_rst_test, rst : std_logic := '1';
begin
x2: UART_RX generic map (
g_CLKS_PER_BIT => c_CLKS_PER_BIT
)
port map( i_Clk => clk,
i_RX_Serial => rx_bit,
o_RX_DV => rx_dv,
o_RX_Byte => rx_byte);
x3: UART_TX generic map (
g_CLKS_PER_BIT => c_CLKS_PER_BIT
)
port map( i_Clk => clk,
i_TX_DV => tx_dv,
i_TX_Byte => tx_byte,
o_TX_Active => tx_active,
o_TX_Serial => tx_bit,
o_TX_Done => tx_done);
u_mig_7series_0 : mig_7series_0
port map (
-- Memory interface ports
ddr3_addr => ddr3_addr,
ddr3_ba => ddr3_ba,
ddr3_cas_n => ddr3_cas_n,
ddr3_ck_n => ddr3_ck_n,
ddr3_ck_p => ddr3_ck_p,
ddr3_cke => ddr3_cke,
ddr3_ras_n => ddr3_ras_n,
ddr3_reset_n => ddr3_reset_n,
ddr3_we_n => ddr3_we_n,
ddr3_dq => ddr3_dq,
ddr3_dqs_n => ddr3_dqs_n,
ddr3_dqs_p => ddr3_dqs_p,
init_calib_complete => init_calib_complete_i,
device_temp => device_temp,
ddr3_cs_n => ddr3_cs_n,
ddr3_dm => ddr3_dm,
ddr3_odt => ddr3_odt,
-- Application interface ports
app_addr => app_addr,
app_cmd => app_cmd,
app_en => app_en,
app_wdf_data => app_wdf_data,
app_wdf_end => app_wdf_end,
app_wdf_wren => app_wdf_wren,
app_rd_data => app_rd_data,
app_rd_data_end => app_rd_data_end,
app_rd_data_valid => app_rd_data_valid,
app_rdy => app_rdy,
app_wdf_rdy => app_wdf_rdy,
app_sr_req => '0',
app_ref_req => '0',
app_zq_req => '0',
app_sr_active => app_sr_active,
app_ref_ack => app_ref_ack,
app_zq_ack => app_zq_ack,
ui_clk => clk,
ui_clk_sync_rst => rst,
app_wdf_mask => app_wdf_mask,
-- System Clock Ports
sys_clk_p => sys_clk_p,
sys_clk_n => sys_clk_n,
-- Reference Clock Ports
clk_ref_p => clk_ref_p,
clk_ref_n => clk_ref_n,
sys_rst => sys_rst
);
process(clk)
begin
-- if(rising_edge(clk)) then
-- if(but(0) = '1') then
-- rst <= '1';
-- end if;
-- end if;
if(rising_edge(clk)) then
case(state) is
when reset =>
--rst <= '1';
led1 <= '0';
led2 <= '0';
state <= init;
when init =>
led2 <= '1';
-- if(count > 20) then
-- rst <= '0';
-- else
-- count <= count + 1;
-- rst <= '1';
-- end if;
--rst <= '0';
app_en <= '0';
app_wdf_end <= '0';
app_wdf_wren <= '0';
app_addr <= (others => '0');
app_cmd <= (others => '0');
app_wdf_data <= (others => '0');
app_wdf_mask <= (others => '0');
if(init_calib_complete_i = '1') then
--led2 <= '1';
state <= idle;
end if;
when idle =>
led1 <= '1';
--led2 <= '1';
tx_dv <= '1';
tx_byte <= X"47";
state <= end_state;
when end_state =>
--led1 <= '1';
--led2 <= '1';
tx_dv <= '0';
when others =>
state <= idle;
end case;
end if;
end process;
end Behavioral;
I tried to implement an adder which is way faster then the average RCA. Therefore I used the XILINX library and found one easy adder called adsu8. I want to embed it into my recent VHDL code. but therefore I have to stick to the data type BIT and BIT_VECTOR. Now every time I synthesise there pops out a bunch of warnings like this:
:Xst:2036 - Inserting OBUF on port > driven by black box . Possible simulation mismatch.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- entity of module
entity rca_8bit is
Port ( OP_A : in BIT_VECTOR (7 downto 0);
OP_B : in BIT_VECTOR (7 downto 0);
ADDSUB : in BIT;
SUM : out BIT_VECTOR (7 downto 0);
FLAGS : out BIT_VECTOR (4 downto 0));
end rca_8bit;
-- architecture describes behavior of module
architecture behavioral of rca_8bit is
-- sub-module is declared
component adsu8
port ( A : in STD_LOGIC_VECTOR (7 downto 0);
B : in STD_LOGIC_VECTOR (7 downto 0);
CI : in BIT;
S : out STD_LOGIC_VECTOR (7 downto 0);
CO : out BIT;
OFL : out BIT);
end component;
-- some code to avoid the blackbox warning message of
-- component adsu8 which is implemented from schematics
attribute box_type : string;
attribute box_type of adsu8 : component is "black_box";
-- additional wires std_logic
signal SIG_A,SIG_B,SIG_S : STD_LOGIC_VECTOR (7 downto 0);
-- additional wires bit
signal SIG_SUM : BIT_VECTOR (7 downto 0);
signal SIG_FLAGS : BIT_VECTOR (4 downto 0);
signal SIG_CO,SIG_OFL : BIT;
begin
-- instantiate and do port map
AS8 : adsu8 port map (SIG_A,SIG_B,ADDSUB,SIG_S,SIG_CO,SIG_OFL);
-- convert and forward std_logic to bit
SIG_A <= to_stdlogicvector(OP_A);
SIG_B <= to_stdlogicvector(OP_B);
SIG_SUM <= to_bitvector(SIG_S);
-- assign result
SUM <= SIG_SUM;
-- generate flags
SIG_FLAGS(0) <= SIG_SUM(7) xor SIG_FLAGS(1); -- S (N xor V)
SIG_FLAGS(1) <= SIG_OFL; -- V
SIG_FLAGS(2) <= SIG_SUM(7); -- N (MSB = 0)
SIG_FLAGS(3) <= '1' when SIG_SUM = "00000000" else '0'; -- Z
SIG_FLAGS(4) <= SIG_CO; -- C
-- assign flags
FLAGS <= SIG_FLAGS;
end behavioral;
I am not this experienced in VHDL but also not that less. But this problem confuses me and causes headache. I am grateful for any solution or information in the right direction.
Thanks in advance and best regards
Tobi
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.
See here.
Cite: The problem is that, for synthesizing, Xilinx assumes every port is either of type std_logic or std_logic_vector (as it generates a new VHDL file that executed the synthesized model, including precise timing simulation). In order for it to work with a synthesizer, you should change the entity definition.
I'm new to VHDL and confused with this design
when Acknwledgement= '1' and clk='1' then
count should be count+1;
and when Acknwledgement= '0' my total counted value of clocks should be assigned to the 'output' and after that resetting count='0' and output='0'.
can anyone help with this.
Thanks in advance.
EDIT:
Code from comment pasted in:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity acknw is
port (acknw : in std_logic;
clk : in std_logic;
output : out integer range 0 to 15);
end acknw;
architecture Behavioral of acknw is
begin
process(clk, acknw) variable c : integer range 0 to 15;
begin
if(clk'event and clk = '1') then
if(acknw = '1') then
c := c+1;
output <= c;
else
c := 0;
output <= c;
end if;
end if;
end process;
end Behavioral;
from your comment it sounds like you want an asynchronous acknw, try something like this:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity acknw is
port (acknw : in std_logic;
clk : in std_logic;
output : out integer range 0 to 15);
end acknw;
architecture Behavioral of acknw is
begin
process(clk, acknw)
begin
if (acknw = '0') then
output <= 0;
elsif rising_edge(clk) then
-- rollover
if (output /= 15) then
output <= output + 1;
else
output <= 0;
end if;
end if;
end process;
end Behavioral;