Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

bitwise function description

Status
Not open for further replies.

Binome

Full Member level 3
Joined
Nov 16, 2009
Messages
152
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,298
Location
Lyon, France
Activity points
2,405
Hi,
I have an input std_logic_vector a. Then I want an output one named r defined (depending on an integer n) as:
r(a'length-1)...r(a'length-n)='0'
r(a'length-1-n)...r(1)=a(a'length-1)...a(n+1)
r(0)=not(a(n))

I've defined a simple function in a package as:
Code:
  function wit_addr(a : std_logic_vector; n : integer) return std_logic_vector is
      variable tmp : std_logic_vector(a'range) := (others => '0');
    begin
      for i in a'length-n to a'length-1 loop
        tmp(i) := '0';
      end loop;
      for i in 1 to a'length-n-1 loop
        tmp(i) := a(i+n);
      end loop;
      tmp(0) := not(a(n));
      return tmp;
    end wit_addr;
but when simulating this testbench:
Code:
library ieee;
use ieee.std_logic_1164.all;

library work;
use work.my_pkg.all;

--------------------------------

entity tb_wit_addr is
end tb_wit_addr;

architecture test of tb_wit_addr is
  signal a, r : std_logic_vector(7 downto 0);
    
begin
  p_test : process
  begin
    a <= "00110011";
    r <= wit_addr(a, 6);

    wait;
  end process;

end test;
the last 2 bits of r are 'U'.
Please tell me why.
 

You should just normalize tmp to be (a'length-1 downto 0) or whatever you prefer using. this solves issues with wit_addr("10001111") or wit_addr(x(15 downto 5). The first has a being 0 to 7, the later doesn't have an index 0.

For the issue at hand, you have no blocking statements between the non-blocking assignment to a and r. you are calling r <= wit_addr("UUUUUUUU", 6); the only bits of a that make it to the output are the lower two.

you need a wait for or wait until in the process, or need to have a variable.
 

I thank you but I don't understand everything:
For now tmp is (a'range). Is it different from making it (a'length-1 downto 0)? (The simulation result is the same).
Then I got a "wait" statement at the end of the process. Is it different from a "wait for" one?
Finally I don't understand the matter about the blocking/non-blocking statements.

Can you explain more precisely? How would you write that?

---------------------------------

I've changed the testbench like that:
Code:
library ieee;
use ieee.std_logic_1164.all;

library work;
use work.my_pkg.all;

--------------------------------

entity tb_wit_addr is
end tb_wit_addr;

architecture test of tb_wit_addr is
  signal a, r : std_logic_vector(7 downto 0);
    
begin
  p_test : process
  begin
    a <= "00110011";
    wait for 10ns;
    r <= wit_addr(a, 3);
    wait for 10ns;
  end process;

end test;
and the result is ok. Now I want to use my function in a component. Is it possible to use it instantly like an AND function (for example) or should I have to use a "wait for" statement somewhere?
 
Last edited:

Functions use "unconstrained vectors" as inputs. This breaks two key assumptions. First, that the input direction is "downto" (or "to") and that element 0 exists. In your case, things just work. However, using functions with constants like "11110000" -- which is a 0 to 7 -- might not work correctly. Likewise, calling a function on a slice of a larger vector like 15 downto 7 could have issues as 0 is not in that range.

There are several threads and google-able blog posts on blocking vs nonblocking assignments.
 

The terminating wait; means wait forever, the process executes only once.

Respectively the value loaded to a is not yet used in the function call because it's updated when the process is finished. If you make a variable, the value is updated immediately.
 

Functions use "unconstrained vectors" as inputs. This breaks two key assumptions. First, that the input direction is "downto" (or "to") and that element 0 exists. In your case, things just work. However, using functions with constants like "11110000" -- which is a 0 to 7 -- might not work correctly. Likewise, calling a function on a slice of a larger vector like 15 downto 7 could have issues as 0 is not in that range.

There are several threads and google-able blog posts on blocking vs nonblocking assignments.

Functions don't have to use unconstrained vectors. They can use parameters that are constrained, so this can be a non issue, though you are constrained to the fixed size in the function description.

Also, non blocking and blocking are verilog terms, not vhdl. The correct terms are signal Vs variable assignment.
 

So tell me. What should I write for my function to be correct and usable as an instant transformation of any std_logic_vector input (as any logic or arithmetic function)?
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top