What happens if VHDL calls an infinite recursive function? - vhdl

What happens in a design if VHDL calls an infinite recursive function? E.g. if I write some random code like:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity recursion is
port ( num : in std_logic_vector(15 downto 0);
exor_out : out std_logic_vector(1 downto 0)
);
end recursion;
architecture Behavioral of recursion is
function exor( num : std_logic_vector ) return std_logic_vector is
variable numf : std_logic_vector(num'length-1 downto 0):=(others => '0');
variable exorf : std_logic_vector((num'length/2)-1 downto 0):=(others => '0');
begin
numf := num;
exorf := exor(numf(num'length-1 downto num'length/2)) xor exor(numf((num'length/2)-1 downto 0));
return exorf;
end exor;
begin
exor_out <= exor(num);
end Behavioral;

Related

VHDL getting a std_logic_vector out of an array of std_logic_vector

I have a Problem. I have an array of std_logic_vector and I input a value unsinged(3 downto 0) and I want to use value as the Index of the array.
So far so good but I should get a std_logic_vector out of the array and put in the Output segments (which is also a std_logic_vector with the same size) but I get the error:
> can't match type conversion with type array type "std_logic_vector"
here is my Code:
> library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity getarrayvalue is
port(
value : in unsigned(3 downto 0);
clk : in std_logic;
segments : out std_logic_vector(6 downto 0)
);
end entity;
architecture v1 of getarrayvalue is
type rom_type is array(0 to 9) of std_logic_vector(6 downto 0);
signal rom: rom_type :=("1111110","0110000","1101101","1111001","0110011","1011011","1011111","1110000","1111111","1111011");
signal val_i: integer;
val_i <= to_integer(value);
process(clk)
begin
if rising_edge(clk) then
segments <= rom_type(val_i);
end if;
end process;
end architecture;
Does anyone know how to fix this problem ? Thanks!

Can't normally see result in wave (Modesim)

I have code designed for Vivid software. How I can translate this code into ModelSIM? In vivado, I should get the following values, but in modelsim I get completely different ones.
This is noise generator. Successful in adding pseudorandom noise sequence to our sine wave, but now we are trying to add Gaussian noise. The code and the simulation results for ADDITION OF PSEUDORANDOM NOISE SEQUENCE TO SINE WAVE IS GIVEN BELOW:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL; --try to use this library as much as possible.
entity sine_wave is
generic ( width : integer := 4 );
port (clk :in std_logic;
random_num : out std_logic_vector (width-1 downto 0);
data_out : out STD_LOGIC_VECTOR(7 downto 0)
);
end sine_wave;
architecture Behavioral of sine_wave is
signal data_out1,rand_temp1,noisy_signal : integer;
signal noisy_signal1 : STD_LOGIC_VECTOR(7 downto 0);
signal i : integer range 0 to 29:=0;
--type memory_type is array (0 to 29) of integer;
type memory_type is array (0 to 29) of std_logic_vector(7 downto 0);
--ROM for storing the sine values generated by MATLAB.
signal sine : memory_type := ("01001101","01011101","01101100","01111010","10000111","10010000","10010111","10011010","10011010");
--hi
begin
process(clk)
variable rand_temp : std_logic_vector(width-1 downto 0):=(width-1 => '1',others => '0');
variable temp : std_logic := '0';
begin
--to check the rising edge of the clock signal
if(rising_edge(clk)) then
temp := rand_temp(width-1) xor rand_temp(width-2);
rand_temp(width-1 downto 1) := rand_temp(width-2 downto 0);
rand_temp(0) := temp;
--data_out <= sine(i);
i <= i+ 1;
if(i = 29) then
i <= 0;
end if;
end if;
data_out <= sine(i);
data_out1<=to_integer(unsigned(sine(i)));
random_num <= rand_temp;
rand_temp1<=to_integer(unsigned(rand_temp));
noisy_signal<=data_out1+rand_temp1;
noisy_signal1<= std_logic_vector(to_signed(noisy_signal,8));
end process;
end Behavioral;
Vivado
ModelSIM

TestBench for Bitwise Operators

Can someone help me to create a TestBench Program for the below Program, please?
library ieee;
use ieee.std_logic_1164.all;
entity bitwise is
port( a,b : in std_logic_vector(4 downto 0);
result1, result2, result3, result4, result5, result6 : out std_logic_vector(4 downto 0));
end bitwise;
architecture arch of bitwise is
begin
result1 <= a and b;
result2 <= a or b;
result3 <= a xor b;
result4 <= not a;
result5 <= to_stdlogicvector(to_bitvector(a) sll 1);
result6 <= to_stdlogicvector(to_bitvector(a) srl 1);
end arch;
My Test Bench Program is below: I am stuck to in the Stimulus process where we have to test each and every possibility. It could be either a loop version or just testing possible numbers for each operator.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
entity test_bitwise is
end test_bitwise;
architecture behavior of test_bitwise is
component bitwise;
port( a,b : in std_logic_vector(4 downto 0);
result1, result2, result3, result4 : out std_logic_vector(4 downto 0));
end component;
--INPUTS
signal tb_a : std_logic_vector(4 downto 0) := (others => '0');
`signal tb_b : std_logic_vector(4 downto 0) := (others => '0');
--OUTPUTS
signal tb_result1 : std_logic_vector(7 downto 0);
signal tb_result2 : std_logic_vector(7 downto 0);
signal tb_result3 : std_logic_vector(7 downto 0);
signal tb_result4 : std_logic_vector(7 downto 0);
begin
-- INSTANTIATE THE UNIT UNDER TEST (UUT)
U1_Test : entity work.test_bitwise(behavioral)
port map (a => tb_a,
b => tb_b,
result1 <= tb_result1,
result2 <= tb_result2,
result3 <= tb_result3,
result4 <= tb_result4);
--STIMULUS PROCESS
stim_proc : process
begin
-- CODE HERE
end process;
end behavior;
As others have stated in the comments, you should provide some input yourself. What have you tried and why didn't it succeed? If you have hard time to find out what to try and how to start, you could begin by doing the following. And if you don't succeed, you can then edit your question or post a new one so the other members can help you.
Use a for loop to iterate over each and every possibility. Writing all the possible values to test by hand would be exhausting.
Because you have two inputs, use two nested for loops inside your process. One iterates the values for input a and the other one for b. Check here how a for loop is written.
Inside the loops, assign values to your signals tb_a and tb_b. The loop indices are integers, so you have to convert them to std_logic_vector type before assigning. Check here for a short tutorial about VHDL conversions.
Add some delay after each iteration with wait.
Print the output values for example to simulator console with report, or you can even use assert statement.

VHDL code to find square root of number?

Is there is any in built function or any library that can be included in the design to find square root of a number?
Restoring square root algorithm is easy to implement on fpga, wikipedia has an example.
FPGA vendors should have cores available, it hides inside the general purpose CORDIC core on Xilinx. They also have square root cores for floating points, if that's what you need.
For non-synthesizable (simulation/test-bench only) operation, square root for real can be done with:
y := math_real.sqrt(x)
For synthesizable operation, see answer from Jonathan Drolet.
This one worked for me.
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_unsigned.ALL;
entity squart is port(
clock : in std_logic;
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(3 downto 0)); end squart;
architecture behaviour of squart is
signal part_done : std_logic := '0';
signal part_count : integer := 3;
signal result : std_logic_vector(4 downto 0) := "00000";
signal partialq : std_logic_vector(5 downto 0) := "000000";
begin
part_done_1: process(clock, data_in, part_done)
begin
if(clock'event and clock='1')then
if(part_done='0')then
if(part_count>=0)then
partialq(1 downto 0) <= data_in((part_count*2)+ 1 downto part_count*2);
part_done <= '1'; else
data_out <= result(3 downto 0);
end if;
part_count <= part_count - 1;
elsif(part_done='1')then
if((result(3 downto 0) & "01") <= partialq)then
result <= result(3 downto 0) & '1';
partialq(5 downto 2) <= partialq(3 downto 0) - (result(1 downto 0)&"01");
else
result <= result(3 downto 0) & '0';
partialq(5 downto 2) <= partialq(3 downto 0);
end if;
part_done <= '0';
end if;
end if;
end process;
end behaviour;
Check this one:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity SQRT is
Generic ( b : natural range 4 to 32 := 16 );
Port ( value : in STD_LOGIC_VECTOR (15 downto 0);
result : out STD_LOGIC_VECTOR (7 downto 0));
end SQRT;
architecture Behave of SQRT is
begin
process (value)
variable vop : unsigned(b-1 downto 0);
variable vres : unsigned(b-1 downto 0);
variable vone : unsigned(b-1 downto 0);
begin
vone := to_unsigned(2**(b-2),b);
vop := unsigned(value);
vres := (others=>'0');
while (vone /= 0) loop
if (vop >= vres+vone) then
vop := vop - (vres+vone);
vres := vres/2 + vone;
else
vres := vres/2;
end if;
vone := vone/4;
end loop;
result <= std_logic_vector(vres(result'range));
end process;
end;

VHDL multiple constant drivers

I'm trying to modify a source code for do a sum (for example) and other maths function using switch and hex display.
This is the main code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.seven_segment_pkg.all;
entity Switch7Segment is
port (
SW : in std_logic_vector(9 downto 0);
HEX0 : out std_logic_vector(6 downto 0);
HEX1 : out std_logic_vector(6 downto 0);
HEX2 : out std_logic_vector(6 downto 0);
HEX3 : out std_logic_vector(6 downto 0);
KEY : in std_logic_vector(3 downto 0);
CLOCK_50 : in std_logic
);
end entity Switch7Segment;
architecture behavior of Switch7Segment is
signal segments1 : std_logic_vector(13 downto 0);
signal segments2 : std_logic_vector(13 downto 0);
signal segmentsR : std_logic_vector(13 downto 0); -- Range changed from 27 downto 0 to allow compile
signal input1 : integer;
signal input2 : integer;
signal result : unsigned(31 downto 0); -- Range added to allow compile
signal temp : integer;
begin
input1 <= to_integer(unsigned(SW(4 downto 0)));
input2 <= to_integer(unsigned(SW(9 downto 5)));
segments1 <= unsigned_to_seven_segment(value => unsigned(SW(4 downto 0)), number_of_digits => 2, value_is_bcd => false);
segments2 <= unsigned_to_seven_segment(value => unsigned(SW(9 downto 5)), number_of_digits => 2, value_is_bcd => false);
HEX1 <= segments1(13 downto 7);
HEX0 <= segments1(6 downto 0);
HEX3 <= segments2(13 downto 7);
HEX2 <= segments2(6 downto 0);
process(CLOCK_50)
begin
if (CLOCK_50' EVENT and CLOCK_50 = '1' AND KEY(0) = '1') then
temp <= input1+input2;
result <= to_unsigned(integer(temp), result'length);
segmentsR <= unsigned_to_seven_segment(value => unsigned(result), number_of_digits => 2, value_is_bcd => false);
HEX1 <= segmentsR(13 downto 7);
HEX0 <= segmentsR(6 downto 0);
end if;
end process;
end architecture;
And then there is the package:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package seven_segment_pkg is
-- Return a std_logic_vector ready for driving a number of 7-segment displays.
function unsigned_to_seven_segment(value : unsigned; number_of_digits : integer; value_is_bcd : boolean)
return std_logic_vector;
end;
package body seven_segment_pkg is
function seven_seg_from_bcd_digit(bcd_digit : std_logic_vector(3 downto 0)) return std_logic_vector is
begin
case bcd_digit is
-- abcdefg
when x"0" => return "1000000";
when x"1" => return "1111001";
when x"2" => return "0100100";
when x"3" => return "0110000";
when x"4" => return "0011001";
when x"5" => return "0010010";
when x"6" => return "0000010";
when x"7" => return "1111000";
when x"8" => return "0000000";
when x"9" => return "0010000";
when x"a" => return "0001000";
when x"b" => return "0000011";
when x"c" => return "1000110";
when x"d" => return "0100001";
when x"e" => return "0000110";
when x"f" => return "1110001";
when others => return "0000000";
end case;
end function;
-- Return a vector ready for driving a series of 7-segment displays.
function unsigned_to_seven_segment(
value : unsigned;
-- Number of 7-segment displays (determines output vector width: W = 7*N)
number_of_digits : integer;
-- When true, treat the input value as a BCD number where every 4 bits hold one
-- digit from 0 to A. When false, treat the input number as an unsigned integer.
value_is_bcd : boolean
) return std_logic_vector is
variable segments : std_logic_vector(number_of_digits*7-1 downto 0);
variable bcd_quotient : unsigned(value'range);
variable bcd_remainder : unsigned(3 downto 0);
begin
if value_is_bcd then
for i in 0 to number_of_digits-1 loop
segments(i*7+6 downto i*7) := seven_seg_from_bcd_digit(
std_logic_vector(value(i*4+3 downto i*4))
);
end loop;
else
bcd_quotient := value;
for i in 0 to number_of_digits-1 loop
bcd_remainder := resize(bcd_quotient mod 10, 4);
bcd_quotient := bcd_quotient / 10;
segments(i*7+6 downto i*7) := seven_seg_from_bcd_digit(
std_logic_vector(bcd_remainder)
);
end loop;
end if;
return segments;
end function;
end package body;
I think that there is an error that at the moment i never signed here that is the length of the result. if we compile this VHDL code Quartus will tell us that the function is for 13 element and not for 27. But i don't see an obstacle to resolve it....my problem is about outputs (HEX0.....HEX3)
If i modify the code and i insert
signal segmentsR: std_logic_vector(13 downto 0);
I resolve the problem of the length but i will see error 10028 (multiple constant drivers).
If i understood correct, i can't assign two times at the same vector two different value or something similar is correct? maybe i always think like a C++ / C programmer. I think that if i use CLOCK the problem will be resolve but is not true...
The problem is that there are drivers for HEX0 and HEX1 both before the process and in the process, but any signal/port should only be driven from one place in typical synthesized code.
If the HEX0 and HEX1 are driven from the process, then remove the drivers before the process.
Conceptually, a multiple drivers error means that your behavioral code (remember: VHDL describes how a circuit works) isn't able to be synthesized. Or, if you have really special synthesizing code, it will give you unexpected results.
In my experience, this error results when I write code with undefined behavior -- for example, if in two processes I modify the same variable (say, X) based on some condition, then the hardware could run into an undefined state where both conditions are met -- how should the variable be modified? If you are familiar to race conditions or mutual exclusion, this should look familiar. Hardware languages don't have easy support for mutex and the like, so they warn you and won't let you do the bad thing.
In your case, I think you could clarify your code and simplify things by assigning default values to your top-level ports, like so:
entity Switch7Segment is
port (
SW : in std_logic_vector(9 downto 0);
HEX0 : out std_logic_vector(6 downto 0);
HEX1 : out std_logic_vector(6 downto 0) := (others => '0');
HEX2 : out std_logic_vector(6 downto 0) := (others => '0');
HEX3 : out std_logic_vector(6 downto 0);
KEY : in std_logic_vector(3 downto 0);
CLOCK_50 : in std_logic
);
end entity Switch7Segment;
This provides a default value for an entity. Whatever creates the entity can provide a different value than the default. Read more here: http://vhdl.renerta.com/mobile/source/vhd00051.htm
It looks like your default value is more complicated (based on the inputs of the function). In this case, I would either (1) change my interface so that the caller provides the information or (2) write a function and a constant in a package and use the function/constant as the default value.
Another possible solution is using generics and default value. This would let you use the bits of the SW field in you default values. (ie: something like HEX2 : out std_logic_vector(6 downto 0) := (SW(xx downto yy), where SW is defined in the generics port)

Resources