VHDL Filter not getting output for first values - vhdl

I tried implementing a fir filter in VHDL but during the first three clocks I get no output and the error at 0 ps, Instance /filter_tb/uut/ : Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)..
Source file (I also have 2 other files for D Flip-Flops):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
entity filter is
port ( x: in STD_LOGIC_VECTOR(3 downto 0);
clk: in STD_LOGIC;
y: out STD_LOGIC_VECTOR(9 downto 0));
end filter;
architecture struct of filter is
type array1 is array (0 to 3) of STD_LOGIC_VECTOR(3 downto 0);
signal coef : array1 :=( "0001", "0011", "0010", "0001");
signal c0, c1, c2, c3: STD_LOGIC_VECTOR(7 downto 0):="00000000";
signal s0, s1, s2, s3: STD_LOGIC_VECTOR(3 downto 0) :="0000";
signal sum: STD_LOGIC_VECTOR(9 downto 0):="0000000000";
component DFF is
Port ( d : in STD_LOGIC_VECTOR(3 downto 0);
clk : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(3 downto 0));
end component;
component lDFF is
Port ( d : in STD_LOGIC_VECTOR(9 downto 0);
clk : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(9 downto 0));
end component;
begin
s0<=x;
c0<=x*coef(0);
DFF1: DFF port map(s0,clk,s1);
c1<=s1*coef(1);
DFF2: DFF port map(s1,clk,s2);
c2<=s2*coef(2);
DFF3: DFF port map(s2,clk,s3);
c3<=s3*coef(3);
sum<=("00" & c0+c1+c2+c3);
lDFF1: lDFF port map(sum,clk,y);
end struct;
Testbench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use ieee.std_logic_unsigned.all;
ENTITY filter_tb IS
END filter_tb;
ARCHITECTURE behavior OF filter_tb IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT filter
PORT(
x : IN STD_LOGIC_VECTOR(3 downto 0);
clk : IN std_logic;
y : OUT STD_LOGIC_VECTOR(9 downto 0)
);
END COMPONENT;
--Inputs
signal x : STD_LOGIC_VECTOR(3 downto 0) := (others => '0');
signal clk : std_logic := '0';
--Outputs
signal y : STD_LOGIC_VECTOR(9 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: filter PORT MAP (
x => x,
clk => clk,
y => y
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc1: process
begin
x<="0001";
wait for 10ns;
x<="0011";
wait for 10ns;
x<="0010";
wait for 10ns;
--x<="0011";
end process;
END;
Output:
If anyonce could help, I'd appreciate it. I think it has something to do with the inital values of the signals c_i and s_i but I'm not too sure.

Your FIR filter contains flip-flops. These flip-flops have no reset input and so power up in an unknown state. You simulator models this by initialising the flip-flops' outputs to "UUUU" (as the are four bits wide). A 'U' std_logic value represents and uninitialised value.
So, your code behaves as you ought to expect. If you're not happy with that behaviour, you need to add a reset input and connect it to your flip-flops.

You have build a series of three register making up a cascade of registers.
You have not provided a reset so the register contents will be Unknown. You use the registers for calculations without any condition. Thus you arithmetic calculations will see the Unknown values and fail as you have seen.
The first (simplest) solution would be to add a reset. But that is not the best solution. You will no longer get warnings but the first three cycles of your output will be based on the register reset value not of your input signal.
If you have a big stream and don't care about some incorrect values in the first clock cycle you can live with that.
The really correct way would be to have a 'valid' signal transported along side your data. You only present the output data when there is a 'valid'. This is the standard method to process data through any pipeline hardware structure.
By the way: you normally do not build D-ffs yourself. The synthesizer will do that for you. You just use a clocked process and process the data vectors in it.
I have some questions. If I add a reset pin, when will I toggle it from 1 to 0? How can I create this circuit without explicitly using D-ffs?
You make a reset signal in the same way as you make your clock.
As to D-registers: they come out if you use the standard register VHDL code:
reg : process (clk,reset_n)
begin
// a-synchronous active low reset
if (reset_n='0') then
s0 <= "0000";
s1 <= "0000";
s2 <= "0000";
elsif (rising_edge(clk)) then
s0 <= x;
s1 <= s0;
s2 <= s1;
....
(Code entered as-is, not checked for syntax or typing errors)

Related

How to implement a test bench file for a 8x1 Multiplexer with 32-bit line width?

I'm writing a VHDL code to model an 8x1 multiplexer where each input has 32-bit width. So I created an array to model the MUX but now I'm stuck with the Test Bench, it's gotten so complicated. Here is my original file (I'm sure it has so many redundancies) How can I actually make the test bench to recognize my array (R_in) from the component's file and then how will I stimulate it?
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY mux8_1 IS
PORT(Rs :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
in0,in1,in2,in3,in4,in5,in6,in7 :IN STD_LOGIC_VECTOR(31 DOWNTO 0);
R_out :OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END mux8_1;
ARCHITECTURE behaviour OF mux8_1 IS
type t_array_mux is array (0 to 7) of STD_LOGIC_VECTOR(31 DOWNTO 0);
signal R_in:t_array_mux;
BEGIN
R_in(0) <= in0;
R_in(1) <= in1;
R_in(2) <= in2;
R_in(3) <= in3;
R_in(4) <= in4;
R_in(5) <= in5;
R_in(6) <= in6;
R_in(7) <= in7;
process(R_in, Rs)
BEGIN
CASE Rs IS
WHEN "000"=>R_out<=R_in(0);
WHEN "001"=>R_out<=R_in(1);
WHEN "010"=>R_out<=R_in(2);
WHEN "011"=>R_out<=R_in(3);
WHEN "100"=>R_out<=R_in(4);
WHEN "101"=>R_out<=R_in(5);
WHEN "110"=>R_out<=R_in(6);
WHEN "111"=>R_out<=R_in(7);
WHEN OTHERS=>R_out<= (others => '0');
END CASE;
END process;
END behaviour;
And here is my "in progress" test bench file. Just ignore the "stimulus process" part I know it's wrong I just couldn't figure out how to write it for a 32-bit signal.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
ENTITY mux8_1_TB IS
END mux8_1_TB;
ARCHITECTURE behaviour OF mux8_1_TB IS
COMPONENT mux8_1
PORT(Rs :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
in0,in1,in2,in3,in4,in5,in6,in7 :IN STD_LOGIC_VECTOR(31 DOWNTO 0);
R_out :OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
type t_array_mux is array (0 to 7) of STD_LOGIC_VECTOR(31 DOWNTO 0);
--Inputs
signal R_in:t_array_mux:=(others=>'0');
signal in0,in1,in2,in3,in4,in5,in6,in7 :STD_LOGIC_VECTOR(31 DOWNTO 0):=(others=>'0');
signal Rs :STD_LOGIC_VECTOR(2 DOWNTO 0):=(others=>'0');
--Outputs
signal R_out:STD_LOGIC_VECTOR(31 DOWNTO 0);
-- Instantiate the Unit Under Test + connect the ports to my signal
BEGIN
R_in(0) <= in0;
R_in(1) <= in1;
R_in(2) <= in2;
R_in(3) <= in3;
R_in(4) <= in4;
R_in(5) <= in5;
R_in(6) <= in6;
R_in(7) <= in7;
uut: mux8_1 PORT MAP(
Rs=>Rs,
R_in=>R_in,
R_out=>R_out
);
-- Stimulus process (where the values -> inputs are set)
PROCESS
begin
R_in<="01010101";
wait for 10 ns;
Rs<="001";
wait for 10 ns;
Rs<="010";
wait for 20 ns;
Rs<="011";
wait for 30 ns;
Rs<="100";
wait for 40 ns;
Rs<="101";
wait for 50 ns;
Rs<="110";
wait for 60 ns;
Rs<="111";
wait for 70 ns;
END PROCESS;
END;
You need to change your uut port map so instead of R_in, it has individual in0 - in7 ports to match your mux8_1 component definition. Then, map in0 - in7 testbench signals directly to these ports:
uut: mux8_1 port map(
...
in0 => in0,
in1 => in1,
...
);
Or if you want to keep the R_in signal, port map like this:
uut: mux8_1 port map(
...
in0 => R_in(0),
in1 => R_in(1),
...
);
This assignment to R_in in your testbench is incorrect:
R_in<="01010101";
R_in is defined as a t_array_mux type, so it can't be assigned a bit vector value. It has to be assigned to an array of 32-bit std_logic_vector. That line should really be removed altogether, as you're already making assignments to R_in in another location outside of the process. Multiple assignments will cause signal contention.
You're initializing R_in in your testbench like this:
signal R_in:t_array_mux:=(others=>'0');
The others keyword as you've used it will only work on an individual std_logic_vector. You need to nest others for your array of std_logic_vector:
signal R_in:t_array_mux:=(others=>(others=>'0'));
You'll want to assign values to your 32-bit in0 - in7 signals so you can see the output of your mux change in the sim. They can be assigned outside the stimulus process. You can assign them using hex-notation (x preceding "") or just binary:
in0 <= x"12345678"; --hex
or
in0 <= "00010010001101000101011001111000"; --binary
Your stimulus process looks fine. As you change Rs, you would expect to see the different input values on R_out. You could add a single wait; at the end of the process, or the process will keep repeating until the end of sim.
Component ports with user-defined types
Alternatively, you could port map your R_in testbench signal directly to a R_in port on your component as you've done, but it would take a bit more work. Your mux8_1 component definition does not have an R_in port. You can add a t_array_mux type port named R_in, if you define the t_array_mux type in a package which you then include in your component and testbench files
library work;
use work.your_package_name.all;
in addition to library IEEE, etc. Then you can use the t_array_mux type in your component port definition:
ENTITY mux8_1 IS
PORT(Rs : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
R_in : IN T_ARRAY_MUX; --User-defined port type
R_out : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END mux8_1;
This will allow you to do the port mapping of your uut the way you currently have it. You'll have to add the package to the project or compile list in whatever tool you're using.
Using a testbench, you can test the correctness/output behavior of your module by giving a sequence of input signals and then comparing the output signals with the expected output.
Firstly, R_in is unknown to your testbench file, as it was an internal signal of your module. So, providing values to that signal doesn't make sense.
Secondly, you need to supply input to your in0, in1, ..., in7 signals, as they seem to drive your output signal R_out, along with the other input signal Rs

VHDL Testbench : Output not changing

I'm currently learning about writing testbenchs for my VHDL components. I am trying to test a clock synchronizer, just made up of two cascaded D-type flip flops. I have written a testbench, supplying a clock and appropriate input signal stimuli but I see no output changing when I simulate, it just remains at "00".
I would be very grateful for any assistance!
EDIT: the dff component is a standard Quartus component, not quite sure how to get at the internal code.
Here is the component VHDL:
library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
--This device is to synchronize external signals that are asynchronous to the
--system by use of two cascaded D-Type flip flops, in order to avoid metastability issues.
--Set the generic term Nbits as required for the number of asynchronous inputs to
--be synchronized to the system clock OUTPUT(0) corresponds to INPUT(0), ect.
entity CLOCK_SYNCHRONIZER is
generic(Nbits : positive := 2);
port
(
--Define inputs
SYS_CLOCK : in std_logic;
RESET : in std_logic;
INPUT : in std_logic_vector(Nbits-1 downto 0);
--Define output
OUTPUT : out std_logic_vector(Nbits-1 downto 0) := (others=>'0')
);
end entity;
architecture v1 of CLOCK_SYNCHRONIZER is
--Declare signal for structural VHDL component wiring
signal A : std_logic_vector(Nbits-1 downto 0);
--Declare D-Type Flip-Flop
component dff
port(D : in std_logic; CLK : in std_logic; CLRN : in std_logic; Q : out std_logic);
end component;
begin
--Generate and wire number of synchronizers required
g1 : for n in Nbits-1 downto 0 generate
c1 : dff port map(D=>input(n), CLK=>sys_clock, Q=>A(n), CLRN=>reset);
c2 : dff port map(D=>A(n), CLK=>sys_clock, Q=>output(n), CLRN=>reset);
end generate;
end architecture v1;
And here is the testbench:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity testbench is
end entity;
architecture v1 of testbench is
component CLOCK_SYNCHRONIZER
generic(Nbits : positive := 2);
port
(
--Define inputs
SYS_CLOCK : in std_logic;
RESET : in std_logic;
INPUT : in std_logic_vector(Nbits-1 downto 0);
--Define output
OUTPUT : out std_logic_vector(Nbits-1 downto 0)
);
end component;
constant Bus_width : integer := 2;
signal SYS_CLOCK : std_logic := '0';
signal RESET : std_logic := '1';
signal INPUT : std_logic_vector(Bus_width-1 downto 0) := (others=>'0');
signal OUTPUT : std_logic_vector(Bus_width-1 downto 0) := (others=>'0');
begin
C1 : CLOCK_SYNCHRONIZER
generic map(Nbits=>Bus_width)
port map(SYS_CLOCK=>SYS_CLOCK, RESET=>RESET, INPUT=>INPUT, OUTPUT=>OUTPUT);
always : process
begin
for i in 0 to 50 loop
INPUT <= "11";
wait for 24ns;
INPUT <= "00";
wait for 24ns;
end loop;
WAIT;
end process;
clk : process
begin
for i in 0 to 50 loop
SYS_CLOCK <= '1';
wait for 5ns;
SYS_CLOCK <= '0';
wait for 5ns;
end loop;
WAIT;
end process;
end architecture v1;
The problem is that you have not compiled an entity to bind to the dff component. See this example on EDA Playground, where you see the following warnings:
ELAB1 WARNING ELAB1_0026: "There is no default binding for component
"dff". (No entity named "dff" was found)." "design.vhd" 45 0 ...
ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__1/c1 : dff not bound.
ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__1/c2 : dff not bound.
ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__0/c1 : dff not bound.
ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__0/c2 : dff not bound.
Given you have no configuration, this needs to have be called dff and must have exactly the same ports as the dff component, ie:
entity dff is
port(D : in std_logic; CLK : in std_logic; CLRN : in std_logic; Q : out std_logic);
end entity;
(Google "VHDL default binding rules")
This needs to model the functionality of the dff flip-flop. I have assumed the following functionality:
architecture v1 of dff is
begin
process (CLK, CLRN)
begin
if CLRN = '0' then
Q <= '0';
elsif rising_edge(CLK) then
Q <= D;
end if;
end process;
end architecture v1;
You can see this now does something more sensible on EDA Playground. (I haven't checked to see whether it is doing the right thing.)
BTW: why are you initialising this output? That seems a strange thing to do:
OUTPUT : out std_logic_vector(Nbits-1 downto 0) := (others=>'0')

Realizing Top Level Entity in Testbench using VHDL

I'm a newbie in VHDL and hardware world.
I'm trying to make a Count&Compare example using Top Level Hierarchy and test it with testbench and see the results on ISIM.
Here is my block diagram sketch:
So I end up these 3 vhd source files:
Counter.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Count_src is
Port ( CLK : in STD_LOGIC;
Reset : in STD_LOGIC;
S : out STD_LOGIC_VECTOR (3 downto 0));
end Count_src;
architecture Behavioral of Count_src is
signal count : STD_LOGIC_VECTOR (3 downto 0);
begin
process (Reset, CLK)
begin
if Reset = '1' then -- Active high reset
count <= "0000"; -- Clear count to 0
elsif (rising_edge(CLK)) then -- Positive edge
count <= count + "0001"; -- increment count
end if;
end process;
S <= count; -- Export count
end Behavioral;
Compare
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Compare_src is
Port ( A : in STD_LOGIC_VECTOR (3 downto 0);
B : in STD_LOGIC_VECTOR (3 downto 0);
S : out STD_LOGIC);
end Compare_src;
architecture Behavioral of Compare_src is
begin
S <= '1' when (A = B) else -- Test if A and B are same
'0'; -- Set when S is different
end Behavioral;
CountCompare (Top Level)
library IEEE;
use IEEE.STD_LOGIC_1164.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 primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity CountCompare_src is
Port ( Clock : in STD_LOGIC;
Reset : in STD_LOGIC;
Value : in STD_LOGIC_VECTOR (3 downto 0);
Flag : out STD_LOGIC);
end CountCompare_src;
architecture Behavioral of CountCompare_src is
-- COMPONENT DECLERATIONS
component counter is
port ( CLK : in std_logic;
Reset : in std_logic;
S : out std_logic_vector(3 downto 0)
);
end component;
component compare is
port (A : in std_logic_vector(3 downto 0);
B : in std_logic_vector(3 downto 0);
S : out std_logic
);
end component;
-- Component Spesification and Binding
for all : counter use entity work.Count_src(behavioral);
for all : compare use entity work.Compare_src(behavioral);
-- Internal Wires
signal count_out : std_logic_vector(3 downto 0);
begin
-- Component instantiation
C1: counter PORT MAP ( Reset => Reset,
CLK => Clock,
S => count_out
);
C2: compare PORT MAP ( A => count_out,
B => Value,
S => Flag
);
end Behavioral;
To test the design I wrote a testbench as follows:
TestBench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY TopLevelTester_tb IS
END TopLevelTester_tb;
ARCHITECTURE behavior OF TopLevelTester_tb IS
--Input and Output definitions.
signal Clock : std_logic := '0';
signal Reset : std_logic := '0';
signal Value : std_logic_vector(3 downto 0) := "1000";
signal Flag : std_logic;
-- Clock period definitions
constant clk_period : time := 1 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.CountCompare_src PORT MAP
(
Clock => Clock,
Reset => Reset,
Value => Value
);
proc: process
begin
Clock <= '0';
wait for clk_period/2;
Clock <= '1';
wait for clk_period/2;
end process;
END;
When I simulate behavioral model, the ISIM pops up, but I see no changes on the Compare Flag. Here is the ss of the ISIM:
What am I missing here? Why does'nt the Flag change?
My best regards.
You have two problems, both in your testbench.
The first is that you never reset count in the counter, it will always be 'U's or 'X's (after you increment it).
The second is that the directly entity instantiation in the testbench is missing an association for the formal flag output to the actual flag signal:
begin
uut:
entity work.countcompare_src
port map (
clock => clock,
reset => reset,
value => value,
flag => flag
);
proc:
process
begin
clock <= '0';
wait for clk_period/2;
clock <= '1';
wait for clk_period/2;
if now > 20 ns then
wait;
end if;
end process;
stimulus:
process
begin
wait for 1 ns;
reset <= '1';
wait for 1 ns;
reset <= '0';
wait;
end process;
Fix those two things and you get:

VHDL testbench for Modelsim (Altera)

I'm in the process of writing the VHDL code for Salsa20 stream cipher. Its main function is the 'quarterround' which I have successfully written. I want to test it in Modelsim before moving on but I am encountering difficulties. I understand I have to 'stimulate' the inputs to observe the outputs. All attempts I've made have resulted in the output, z, not giving any values.
The code for the Quarterround (which is top level):
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY quarter_round is
GENERIC(l:integer:=9);
PORT(y : in unsigned(127 downto 0);
z : out unsigned( 127 downto 0)
);
END quarter_round;
ARCHITECTURE quarter_round_arch of quarter_round is
COMPONENT left is
GENERIC(l:integer);
PORT( a: in unsigned( 31 downto 0);
b: out unsigned( 31 downto 0));
end COMPONENT;
signal i1,i2,i3,i4 :unsigned( 31 downto 0);
signal j1,j2,j3,j4 :unsigned( 31 downto 0);
signal z0,z1,z2,z3 :unsigned( 31 downto 0);
signal y0 : unsigned( 31 downto 0);
signal y1 : unsigned( 31 downto 0);
signal y2 : unsigned( 31 downto 0);
signal y3 : unsigned( 31 downto 0);
BEGIN
y0 <=y(127 downto 96);
y1 <=y(95 downto 64);
y2 <=y(63 downto 32);
y3 <=y(31 downto 0);
i1<=y0+y3;
a1:left generic map(7) port map(i1,j1);
z1<=j1 xor y1;
i2<=z1+y0;
a2:left generic map(9) port map(i2,j2);
z2<=j2 xor y2;
i3<=z2+z1;
a3:left generic map(13) port map(i3,j3);
z3<=j3 xor y3;
i4<=z3+z2;
a4:left generic map(18) port map(i4,j4);
z0<=j4 xor y0;
z<=z0&z1&z2&z3;
END quarter_round_arch;
The COMPONENT left:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY left is
GENERIC (l:integer:=7);
PORT( n: in unsigned( 31 downto 0);
m: out unsigned( 31 downto 0));
END left;
ARCHITECTURE dataflow of left is
begin
m<=n(31-l downto 0)& n(31 downto 31-l+1);
END dataflow;
The testbench I'm trying to write will be assigned a value for y (128 bits), process the function and z should output the correct answer in Modelsim. I realize this is a basic VHDL question, but it's driving me nuts!
This code is failing Modelsim:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY quarter_round_vhd_tst IS
END quarter_round_vhd_tst;
ARCHITECTURE test of quarter_round_vhd_tst IS
COMPONENT quarter_round
PORT (
y : IN STD_LOGIC_VECTOR(127 DOWNTO 0);
z : OUT STD_LOGIC_VECTOR(127 DOWNTO 0)
);
END COMPONENT;
SIGNAL clk : std_logic := '0';
SIGNAL reset : std_logic := '0';
SIGNAL y : STD_LOGIC_VECTOR(127 DOWNTO 0);
SIGNAL z : STD_LOGIC_VECTOR(127 DOWNTO 0);
BEGIN
DUT : quarter_round
PORT MAP (
y => y,
z => z
);
y <= x"201f1e1d1c1b1a191817161514131211";
PROCESS
BEGIN
clk <= '0' ;
wait for 10 ns;
z <= y ;
clk <= '1';
wait for 10 ns;
END PROCESS;
END test;
Edit: this is latest attempt. Code is compiling but Modelsim giving errors saying types do not match.. Any ideas appreciated. CT
david_koontz#Macbook: ghdl -a quarter_round.vhdl
david_koontz#Macbook: ghdl -e quarter_round_vhd_tst
quarter_round.vhdl:100:1: type of signal interface "y" from component
"quarter_round" and port "y" from entity "quarter_round" are not
compatible for an association quarter_round.vhdl:100:1: type of
signal interface "z" from component "quarter_round" and port "z" from
entity "quarter_round" are not compatible for an association ghdl:
compilation error
So the problem you describe after the edit shows up during elaboration. Note the type in the component declaration and the entity quarter_round don't match.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity quarter_round_vhd_tst is
end quarter_round_vhd_tst;
architecture test of quarter_round_vhd_tst is
component quarter_round
port (
y: in unsigned(127 downto 0);
z: out unsigned(127 downto 0)
);
end component;
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal y : unsigned(127 downto 0);
signal z : unsigned(127 downto 0);
begin
DUT: quarter_round
port map (
y => y,
z => z
);
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if Now > 30 ns then
wait;
end if;
end process;
STIMULUS:
process
begin
wait for 10 ns;
y <= x"201f1e1d1c1b1a191817161514131211";
wait for 10 ns;
-- z <= y ;
wait;
end process;
end test;
The changes are for a separate process for clock, likely you'll need it once you add more in. You originally tried to assign z in the testbench, z is an output of quarter_round.
I moved the y assignment into the stimulus process. If the reset gets used you can put that in there too.
The idea behind using wait statements without arguments is to stop processes from repeating endlessly. As long as you assign signals they'd go until Time'HIGH. The comparison for Now in process CLOCK can be changed for multiple stimulus or length of time to execute. Likewise you can introduce a signal used to stop the clock that is assigned in a process (e.g. STIMULUS) that is used instead of Now to stop the clock, if there's something coming out of the (eventual) model that signals end of simulation.
Without the DUT relying on clock (or reset) as soon as y is assigned, z is assigned with the result. (This is why I put the delay before the y assignment, to demonstrate this).
I used the quarter_round and left I corrected yesterday, so mine has a and b instead of m and n.
So does the result look right?
Once over the hurtle of getting something back, then sequential (clocked) processes and you should start making good progress.
And you can use type conversions in the port map for quarter round:
signal y : std_logic_vector(127 downto 0);
signal z : std_logic_vector(127 downto 0);
begin
DUT: quarter_round
port map (
y => unsigned(y),
std_logic_vector(z)=> z
);
But the component declaration still needs to match the entity declaration for quarter_round.
And if you're sure you'll never need to configure quarter_round in the testbench you can use direct entity instantiation, eliminating the component declaration:
-- component quarter_round
-- port (
-- y: in unsigned(127 downto 0);
-- z: out unsigned(127 downto 0)
-- );
-- end component;
...
begin
DUT: -- quarter_round
entity work.quarter_round
port map (
y => unsigned(y),
std_logic_vector(z)=> z
);
It's generally useful to have a valid component declaration or to at least use formal association (instead of positional, the above shows formal). That way someone reading the code doesn't have to count arguments while looking somewhere else.
Notice the directly instantiated entity is specified with a selected name specifying the library the entity is found in.
You must have overlooked the compilation errors relating to "left.vhd". Signals "a" and "b" are undeclared.

Why Does This VHDL Work in Sumulation and Does not Work on the Virtex 5 Device

I have spent the whole day trying to solve the following problem. I am building a small averaging multichannel oscilloscope and I have the following module for storing the signal:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
entity storage is
port
(
clk_in : in std_logic;
reset : in std_logic;
element_in : in std_logic;
data_in : in std_logic_vector(11 downto 0);
addr : in std_logic_vector(9 downto 0);
add : in std_logic; -- add = '1' means add to RAM
-- add = '0' means write to RAM
dump : in std_logic;
element_out : out std_logic;
data_out : out std_logic_vector(31 downto 0)
);
end storage;
architecture rtl of storage is
component bram is
port
(
clk : in std_logic;
we : in std_logic;
en : in std_logic;
addr : in std_logic_vector(9 downto 0);
di : in std_logic_vector(31 downto 0);
do : out std_logic_vector(31 downto 0)
);
end component bram;
type state is (st_startwait, st_add, st_write);
signal current_state : state := st_startwait;
signal next_state : state := st_startwait;
signal start : std_logic;
signal we : std_logic;
signal en : std_logic;
signal di : std_logic_vector(31 downto 0);
signal do : std_logic_vector(31 downto 0);
signal data : std_logic_vector(11 downto 0);
begin
ram : bram port map
(
clk => clk_in,
we => we,
en => en,
addr => addr,
di => di,
do => do
);
process(clk_in, reset, start)
begin
if rising_edge(clk_in) then
if (reset = '1') then
current_state <= st_startwait;
else
start <= '0';
current_state <= next_state;
if (element_in = '1') then
start <= '1';
end if;
end if;
end if;
end process;
process(current_state, start, dump)
variable acc : std_logic_vector(31 downto 0);
begin
element_out <= '0';
en <= '1';
we <= '0';
case current_state is
when st_startwait =>
if (start = '1') then
acc(11 downto 0) := data_in;
acc(31 downto 12) := (others => '0');
next_state <= st_add;
else
next_state <= st_startwait;
end if;
when st_add =>
if (add = '1') then
acc := acc + do;
end if;
we <= '1';
di <= acc;
next_state <= st_write;
when st_write =>
if (dump = '1') then
data_out <= acc;
element_out <= '1';
end if;
next_state <= st_startwait;
end case;
end process;
end rtl;
Below is the BRAM module as copied from the XST manual. This is a no-change type of BRAM and I believe there is the problem. The symptom is that, while this simulates fine, I read only zeroes from the memory when I use the design on the device.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity bram is
port
(
clk : in std_logic;
we : in std_logic;
en : in std_logic;
addr : in std_logic_vector(9 downto 0);
di : in std_logic_vector(31 downto 0);
do : out std_logic_vector(31 downto 0)
);
end bram;
architecture rtl of bram is
type ram_type is array (0 to 999) of std_logic_vector (31 downto 0);
signal buf : ram_type;
begin
process(clk, en, we)
begin
if rising_edge(clk) then
if en = '1' then
if we = '1' then
buf(conv_integer(addr)) <= di;
else
do <= buf(conv_integer(addr));
end if;
end if;
end if;
end process;
end rtl;
What follows is a description of the chip use and the expected output. "clk_in" is a 50 MHz clock. "element_in" is '1' for 20 ns and '0' for 60 ns. "addr_in" iterates from 0 to 999 and changes every 80 ns. "element_in", "data_in", and "addr" are all aligned and synchronous. Now "add" is '1' for 1000 elements, then both "add" and "dump" are zero for 8000 elements and, finally "dump" is '1' for 1000 elements. Now, if I have a test bench that supplies "data_in" from 0 to 999, I expect data_out to be 0, 10, 20, 30, ..., 9990 when "dump" is '1'. That is according to the simulation. In reality I get 0, 1, 2, 3, ..., 999....
Some initial issues to address are listed below.
The process(current_state, start, dump) in storage entity looks like it is
intended to implement a combinatorial element (gates), but the signal (port)
data_in is not in the sensitivity list.
This is very likely to cause a difference between simulation and synthesis
behavior, since simulation will typically only react to the signals in the
sensitivity list, where synthesis will implement the combinatorial design and
react on all used signals, but may give a warning about incomplete sensitivity
list or inferred latches. If you are using VHDL-2008 then use can use a
sensitivity list of (all) to have the process sensitivity to all used
signals, and otherwise you need to add missing signals manually.
The case current_state is in process(current_state, start, dump) lacks an
when others => ..., so the synthesis tool has probably given you a warning
about inferred latches. This should be fixed by adding the when others =>
with and assign all signals driven by the process to the relevant value.
The use clause lists:
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
But both of these should not be used at the same time, since they declare some
of the same identifiers, for example is unsigned declared in both. Since the
RAM uses std_logic_unsigned I suggest that you stick with that only, and
delete use of numeric_std. For new code I would though recommend use of
numeric_std.
Also the process(clk_in, reset, start) in storage entity implements a
sequential element (flip flop) sensitive to only rising edge of clk_in, so
the two last signals in sensitivity list ..., reset, start) are unnecessary,
but does not cause a problem.

Resources