I'm very new in VHDL and having a problem about assigning values I guess.
Let's say that I've a module that get an 16 bit input signal noisein_mono
for every positive edge of the clock source. What I want is to construct a 20 Kbit long bit vector from this 16-bit inputs. So I'm gonna perform random number tests on it FIPS_140-2
The code I end up with is shown below:
-- Entity Decleration
entity MonoTestModule is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
start : in STD_LOGIC;
noisein_mono : in STD_LOGIC_VECTOR (15 downto 0);
running_mono : out STD_LOGIC;
tok_mono : out STD_LOGIC
);
end MonoTestModule;
architecture Behavioral of MonoTestModule is
-- Signal to communication between processes.
signal enable_20k_bit_stream : std_logic;
begin
process (rst, clk, start, noisein_mono)
variable count : integer := 0;
variable twnty_k_bit_stream : bit_vector(19999 to 0);
begin
if(start = '1') then
if (rising_edge(clk)) then
count := count + 1;
twnty_k_bit_stream := twnty_k_bit_stream or to_bitvector(noisein_mono);
twnty_k_bit_stream := twnty_k_bit_stream sll 16;
end if;
if (rst = '1') then
count := 0;
enable_20k_bit_stream <= '0';
end if;
-- if count is reached to 1250, 20kbit is constructed.
if(count = 1250) then
enable_20k_bit_stream <= '1';
else
enable_20k_bit_stream <= '0';
end if;
end if;
end process;
I'm using Xilinx ISE 14.7. The compiler pops up error says Line 52: Unequal length arguments for operator "or". How can I solve this problem?
My best regards.
In simulation this would be two different run-time errors.
There's actually two bounds mismatch errors, one for the "or" on two array values:
twnty_k_bit_stream := twnty_k_bit_stream or
to_bitvector(noisein_mono);
And one for the assignment to twnty_k_bit_stream
where the length doesn't match following an implicit subtype conversion.
And that's because
variable twnty_k_bit_stream : bit_vector(19999 to 0);
that to
should be downto
. When the direction is wrong you'll end up with a null range (an array with no elements).
See IEEE Std 1076-2008 9.2.2 Logical operators, para 3:
If both operands are one-dimensional arrays, the operands shall be arrays of the same length, the operation is performed on matching elements of the arrays, and the result is an array with the same index range as the left operand. If one operand is a scalar and the other operand is a one-dimensional array, the operation is performed on the scalar operand with each element of the array operand. The result is an array with the same index range as the array operand.
So uneven length arrays don't work.
Also see 10.6.2.1 (Variable assignment), paras 5 and 7:
For the execution of a variable assignment whose target is a variable name, the variable name and the expression are first evaluated. A check is then made that the value of the expression belongs to the subtype of the variable, except in the case of a variable that is of a composite type (in which case the assignment involves a subtype conversion). Finally, each subelement of the variable that is not forced is updated with the corresponding subelement of the expression. A design is erroneous if it depends on the order of evaluation of the target and source expressions of an assignment statement.
...
An error occurs if the aforementioned subtype checks fail.
And that error occurs if there isn't a corresponding element in both the target and right hand side expression of the variable assignment.
5.3.2.2 Index constrains and discrete ranges, para 4:
An array constraint of the first form is compatible with the type if, and only if, the constraint defined by each discrete range is compatible with the corresponding index subtype and the array element constraint, if present, is compatible with the element subtype of the type. If any of the discrete ranges defines a null range, any array thus constrained is a null array, having no elements. An array value satisfies an index constraint if at each index position the array value and the index constraint have the same index range. (Note, however, that assignment and certain other operations on arrays involve an implicit subtype conversion.)
Fix both those things:
begin
process (rst, clk) -- , start, noisein_mono) -- not needed
variable count: integer := 0;
variable twnty_k_bit_stream: bit_vector(19999 downto 0); -- was to
begin
if start = '1' then
if rising_edge(clk) then
count := count + 1;
-- twnty_k_bit_stream := twnty_k_bit_stream or
-- to_bitvector(noisein_mono);
-- twnty_k_bit_stream := twnty_k_bit_stream sll 16;
twnty_k_bit_stream (twnty_k_bit_stream'LEFT downto noisein_mono'LENGTH) :=
twnty_k_bit_stream (twnty_k_bit_stream'LEFT - noisein_mono'LENGTH downto 0);
twnty_k_bit_stream (noisein_mono'RANGE) :=
to_bitvector(noisein_mono);
end if;
noting I also fixed the sensitivity list and we get something that doesn't have a bounds check error. Instead of using an "or" this shifts then writes the lower 16 bits with noisein_mono
.
Adding a testbench:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity monoblahblah_tb is
end entity;
architecture foo of monoblahblah_tb is
signal clk: std_logic := '0';
signal rst: std_logic;
signal start: std_logic;
signal noisein_mono: std_logic_vector (15 downto 0);
signal running_mono: std_logic;
signal tok_mono: std_logic;
begin
DUT:
entity work.monotestmodule
port map (
clk => clk,
rst => rst,
start => start,
noisein_mono => noisein_mono,
running_mono => running_mono,
tok_mono => tok_mono
);
CLOCK:
process
begin
wait for 5 ns;
clk <= not clk;
if now > 12680 ns then
wait;
end if;
end process;
STIMULI:
process
begin
wait for 6 ns;
rst <= '0';
start <= '0';
noisein_mono <= (others => '0');
wait for 10 ns;
rst <= '1';
wait for 10 ns;
rst <= '0';
wait for 100 ns;
start <= '1';
for i in 0 to 1249 loop -- 20,000 / 16
noisein_mono <=
std_logic_vector(to_unsigned(i, noisein_mono'length))
xor
x"dead";
wait for 10 ns;
end loop;
wait;
end process;
end architecture;
And we get:
And if I had thought about it I would have XOR'd different values in consecutively, these values are simply unique from 0 to 1249 as binary XOR'd with x"DEAD". (It seemed outré to write a random number generator for a simple testbench, considering the state of twnty_k_bit_stream
isn't displayed. The purpose is to show there are no bounds check failures.)
So there were two semantic errors detectable at run time (or synthesis) and an incorrect sensitivity list.