I would like to add zero at the lsb (zero padding). my input is
m : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
and another vector (lets say a) that his length is changing all the time.
I didn't manage doing that by using bitwise "OR" because the length is always not the same.
Assuming you don't know the length of a, but want to zero pad the LSB of the resulting vector b it to length of b.
b(b'left downto b'left - a'left) <= a;
b(b'left - a'left - 1 downto 0) <= (others => '0');
I hope I didn't mix up the - 1.
Related
im making a signed adder and i need to increase the data_width and then take the MSB of the input and assign it to the MSB of the longer Variable for example with a 4 bit input of 1010 i have turned it to z1010 but i need to 11010 and for a 0110 i can change it to z0110 and need to make it 00110
port (
A : in std_logic_vector ((DATA_WIDTH-1) downto 0);
B : in std_logic_vector ((DATA_WIDTH-1) downto 0);
SUM : out std_logic_vector (DATA_WIDTH downto 0)
);
end entity;
architecture v1 of DeMUX is
-- start
begin
DeMUX : process (A, B) is
variable AA : std_logic_vector((DATA_WIDTH-1) downto 0);
variable BB : std_logic_vector((DATA_WIDTH-1) downto 0);
variable CA : std_logic_vector((DATA_WIDTH) downto 0);
variable SUMMER : std_logic_vector(((DATA_WIDTH-1)) downto 0);
variable SUMMER2 : std_logic_vector((DATA_WIDTH) downto 0);
begin
-- so the sum is the Xor of A and B. however you also need to include the carry bit as it might not fit this means
--you and A and B to find C if MSB of AB = 0 & C= 1 add 1 to sum
AA := A;
BB := B;
SUM <= std_logic_vector(resize(signed(AA), SUM'length));
SUM <= std_logic_vector(resize(signed(BB), SUM'length));
AA(DATA_WIDTH) := A(DATA_WIDTH);
BB(DATA_WIDTH) := B(DATA_WIDTH);
i receive an error of, index value 4 is outside the range (3 down to 0) of object "a"
any advice is welcome
You can't declare a fixed size output :
SUM : out std_logic_vector (DATA_WIDTH downto 0)
and affect it with variable size signals :
SUM <= std_logic_vector(resize(signed(AA), SUM'length));
SUM <= std_logic_vector(resize(signed(BB), SUM'length));
To do things properly, affect you signal SUM with a fixed size, whether the size of the addition is DATA_WIDTH or DATA_WIDTH + 1
SLP
I am receiving an error that says my target is 17 bits but the source is 33 bits. I don't understand how this is the case when the two things being added together are each 16 bits. This should result in a 17-bit sum. I am unsure as to how it comes to 33 bits.
I have tried converting each addend into an sfixed value because that is what the target is. I have tried without this conversion. I have tried using the resize function on each addend in order to guarantee each is 16 bits. This method worked but created an incorrect circuit.
N and I are both generic integers of value 4.
This is the problem statement:
wx12 <= wx(1*(4*N)-1 downto 0*(4*N)) + wx(2*(4*N)-1 downto 1*(4*N));
This is wx and how it is defined/populated:
signal wx : sfixed (4*N*I-1 downto 0);
wx(1*(4*N)-1 downto 0*(4*N)) <= x(1*(2*N)-1 downto 0*(2*N)) * w(1*(2*N)-1 downto 0*(2*N));
wx(2*(4*N)-1 downto 1*(4*N)) <= x(2*(2*N)-1 downto 1*(2*N)) * w(2*(2*N)-1 downto 1*(2*N));
wx(3*(4*N)-1 downto 2*(4*N)) <= x(3*(2*N)-1 downto 2*(2*N)) * w(3*(2*N)-1 downto 2*(2*N));
wx(4*(4*N)-1 downto 3*(4*N)) <= x(4*(2*N)-1 downto 3*(2*N)) * w(4*(2*N)-1 downto 3*(2*N));
This is w and how it is defined:
constant w : sfixed ((2*N*I)-1 downto 0) := to_sfixed(1, N-1, -N)
& to_sfixed(1, N-1, -N)
& to_sfixed(1, N-1, -N)
& to_sfixed(1, N-1, -N);
This is x and how it is defined:
x : in sfixed ((2*N*I)-1 downto 0);
I expected a result of 17 bits but the error below shows the result is actually 33 bits.
[Synth 8-690] width mismatch in assignment; target has 17 bits, source has 33 bits ["C:/Users/devon/project_1/project_1.srcs/sources_1/new/neural_network.vhd":104]
If N and I are 4, then you have this:
wx12 <= wx(15 downto 0) + wx(31 downto 16);
The fixed_point libraries, by default, behave differently to numeric_std.
Both operands are re-shaped to be (max(a,b) downto (min(a,b))
The result has bit growth.
Because max(a,b) = 31, and min(a,b) = 0, both operands are bit extended to (31 downto 0) - 32 bit. It then has a single bit of growth, giving the result.
This is all because the fixed point libraries respects the index as the 2^n. to do what you want, you need to re-align the 2nd operand to (15 downto 0) yourself.
Suppose I have a vector :
action_complete: in std_logic_vector(n-1 downto 0)
How do I compare (inside the if statement) if PART of the vector is all zeros, where the comparison range depends on J (integer)? The integer is being changed inside the same process (state machine working with clock), but in other state.
Example code of what I want to do:
when s1 =>
J<=J+1;
when s2 =>
if action_complete(J-1 downto 0)=('all zeros') then ..
signal a : std_logic_vector (7 downto 0) := (others => '0');
a <= a (6 downto 0) & '0';
So I understand that a is a signal that is 8 bits and all of those bits are 0. Is the next line assigning bits 6 down to 0 to be zero again?
Maybe the equivalent syntax would help understand:
a(7 downto 0) <= a(6 downto 0) & '0';
So a(7) gets the value of a(6), a(6) the value of a(5), ... and a(0) is '0'.
This code describe a shift register (assuming the statement is enclosed in a synchronous process, which should be to prevent combinational loop) where values are shifted left every cycle.
In VHDL, & is the concatenation operator. So "0101" & "1010" is equal to "01011010". In your example, the 7 LSBs are concatenated to a logical zero to form a new shifted 8 bits vector.
It's a very short definition for shifting the bits to the left by replacing rightmost bit with '0'.
For the fixed point arithmatic I represented 0.166 with 0000 0010101010100110 and multiply it with same. for this I wrote the code in VHDL as below. Output is assigned in y which is signed 41bit. For signed Multiplication A(a1,b1)*A(a2,b2)=A(a1+a2+1,b1+b2). However during the simulation its give an error
Target Size 41 and source size 40 for array dimension 0 does not match.
code:
entity file1 is
Port ( y : out signed(40 downto 0));
end file1;
architecture Behavioral of file1 is
signal a : signed(19 downto 0) := "00000010101010100110";
signal b : signed(19 downto 0) := "00000010101010100110";
begin
y<= (a*b); ----error
end Behavioral;
The result of multiplying 19+1 bits to 19+1 bits is 39+1 bits, while your port is 40+1 bit long. For example let's multiply maximum possible values for 19-bits: 0x7FFFF * 0x7FFFF = 0x3FFFF00001 - so it's 39 bits (19 + 19 + carry) for unsigned result and +1 bit for sign.
So you should either "normalize" result by extending it to 1 more bit, which should be equal to the sign of result (bit#40 = bit#39) or just choose 40-bit port as output:
Port ( y : out signed(39 downto 0))
If you really need redundant 41st bit:
begin
y(39 downto 0) <= (a*b)
y(40) <= y(39)
end Behavioral;
Or just use resize function for signeds: How to convert 8 bits to 16 bits in VHDL?