How I make an output logic signal a real output pin? - vhdl

I am trying to take this signal :
signal Fx3_bridge : std_logic_vector (1 downto 0);
To this output port:
Fx3_A : out std_logic;
I also want to discard the less significant bit of my logic vector.

A std_logic_vector is an array. Your std_logic_vector
signal Fx3_bridge : std_logic_vector (1 downto 0);
has two elements - 1 and 0. You index arrays in VHDL using brackets, so the most significant bit (strictly speaking: the left hand element) is
Fx3_bridge(1)
So, you want something like:
Fx3_A <= Fx3_bridge(1);

Related

VHDL syntax to output a signal value

I am trying to learn the syntax of VHDL. I wrote a simple algorithm using a counter and an LED.
in the port section, I have...
LED : OUT STD_LOGIC_VECTOR(7 downto 0);
Below port, I have...
signal cntr : natural range 0 to (2**30);
I have a process that increments cntr.
After the process, I have...
LED(7 downto 0) <= std_logic_vector (to_signed(cntr(29 downto 22)));
I am trying to blink the LEDs to show the count. I need help in the line above where I am trying to convert a signal to a std_logic_vector and match 8 bits with the LED.

how to make std_logic_vector consist of std_logic_vectorin vhdl

I have such signal:
sw : std_logic_vector(7 downto 0);
and now I want to make another one, which will have it as upper bits, 1 the rest:
std_logic_vector(31 downto 0) := (7 downto 0 => sw, others => '1');
but it won't compile. any help please? I don't want to do it bit by bit.
I'm not entirely sure where should go this smaller signal, but you probably want to do this:
signal sw: std_logic_vector(7 downto 0);
signal big: std_logic_vector(31 downto 0);
big <= sw & x"FFFFFF";
This will assign sw vector to 8 most significant bits of big vector, and '1' to rest of bits. Write in comments, if you want to do something else.
What you are trying to do is assign a signal -which is variable- to another signal during initialization. What do you expect to happen?
I.e. at the moment you define a signal, you can only initialize it. If you want to assign something to the signal, you have to write a declaration.
definition -> initialization
declaration -> assignment
So in this case you can define big a larger range, and fix the constant bits in initialization
signal big : std_logic_vector(31 downto 0) => (others => '1');
And when you want to assign sw to any part of big, do that after the begin.
big(31 downto 24) <= sw;
or
big(7 downto 0) <= sw;
etc. The bits you initialized as '1' will be overwritten by the assignment.

VHDL multiple std_logic_vector to one large std_logic_vector

I have four std_logic_vectors (15 downto 0) and want to stack them into a std_logic_vector (63 downt 0) so fare I have found one way of doing it but is it the correct way or is there a more optimal and correct way to do it?
signal slv16_1,slv16_2,slv16_3,slv16_4 : std_logic_vector(15 downto 0);
signal slv64 : std_logic_vector(63 downto 0);
slv64(15 downto 0) <= slv16_1;
slv64(31 downto 16) <= slv16_2;
slv64(47 downto 32) <= slv16_3;
slv64(63 downto 48) <= slv16_4;
An easy way to accomplish this is to use the concatenation operator &. It achieves the same thing you did above, but with less code required.
slv64 <= slv16_4 & slv16_3 & slv16_2 & slv16_1;
Since the source vectors have unique names, I don't see a way to automate this. What you might be able to try is to never use the 16-bit vectors, and instead use slices of the larger 64 bit vector. So instead of an assignment like this:
slv16_1 <= "0101110000111010";
Use
slv64(15 downto 0) <= "0101110000111010";
Or instead of an entity instantiation where you connect slv16_2 like this:
output_port => slv16_2,
Use
output_port => slv64(31 downto 16),
I would really need to see more of your code to understand what might work best, but my basic answer is 'use the larger vector in the first place'.
If you can't do this for some reason, an alternative would be to declare your 16-bit vectors as an array of arrays:
type slv16_array_type is array (integer range <>) of std_logic_vector(15 downto 0);
signal slv16_array : slv16_array_type(3 downto 0);
You could then assign to the elements like this:
slv16_array(0) <= "0101";
You could combine the elements of this type with a generate loop:
slv16_combine : for i in 0 to 3 generate
slv64((16*(i+1))-1 downto 16*i) <= slv16_array(i);
end generate;
VHDL guide says that this one should work:
slv64 <= (slv16_4, slv16_3, slv16_2, slv16_1);

How do I split 16-bit data into 2 8-bit data in VHDL?

How do I split 16-bit data into 2 8-bit data?
signal part : std_logic_vector (16 downto 0);
signal part_1 : std_logic_vector (8 downto 0);
signal part_2 : std_logic_vector (8 downto 0);
The part is actually 17 bit, since 16 downto 0 is a 17 bit range, and the part_* are likewise 9 bit.
If the ranges are 15 downto 0 and 7 downto 0, then you can do the split with:
part_1 <= part( 7 downto 0);
part_2 <= part(15 downto 8);
Btw, quote by Martin Fowler / Phil Karlton:
There are two hard things in computer science:
cache invalidation, naming things, and off-by-one errors.
Why are your signals 17 bits and 9 bits long? I think they should be 16 and 8...
signal part : std_logic_vector (15 downto 0);
signal part_1 : std_logic_vector (7 downto 0);
signal part_2 : std_logic_vector (7 downto 0);
begin -- architecture begin
part_1 <= part(15 downto 8);
part_2 <= part(7 downto 0);
Pretty simple stuff... I'm surprised you didn't run across this in looking at a VHDL example.
There's also aggregate target assignment:
library ieee;
use ieee.std_logic_1164.all;
entity foo is
end entity;
architecture fum of foo is
type fie is array (natural range 0 to 1) of std_logic_vector (7 downto 0);
signal part: std_logic_vector (15 downto 0);
signal part_1: std_logic_vector (7 downto 0);
signal part_2: std_logic_vector (7 downto 0);
begin
(part_1, part_2) <= fie'(part(15 downto 8), part(7 downto 0));
end architecture;
Which is admittedly more useful for extracting elements of records in one fell swoop. What's slick here is that there's no place there's any named signal of type fie.
The reason for the aggregate on the right hand side is because the element size has to match on both sides of the assignment operator, both aggregates are treated as if they are type fie.
Doing this with records allows you to extract elements of varying sizes. Extracting fields from CPU machine instruction formats comes to mind. It allows you to use simple names without requiring aliases for element selected names. (There would be no named record).
When the element size is the same on both sides you can simply use a target aggregate:
library ieee;
use ieee.std_logic_1164.all;
entity fie is
end entity;
architecture fum of fie is
signal part: std_logic_vector (2 downto 0);
signal part_1: std_logic;
signal part_2: std_logic;
signal part_3: std_logic;
begin
(part_1, part_2, part_3) <= part;
end architecture;
These aggregates all use positional association. You can also use named association. Record aggregates require an others choice represent at least one element and all the elements have to have the same type (e.g. std_logic_vector).
Just for completeness: you can also use aliases which makes the signal assignment obsolete:
signal part : std_logic_vector (15 downto 0);
alias part_1 : std_logic_vector(7 downto 0) is part(15 downto 8);
alias part_2 : std_logic_vector(7 downto 0) is part(7 downto 0);

Is my VHDL sentence allowed?

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_1164_unsigned.all;
ENTITY alu IS
PORT (a: IN STD_LOGIC_VECTOR (15 DOWNTO 0);
b: IN STD_LOGIC_VECTOR (15 DOWNTO 0);
operation: IN INTEGER (1 TO 10);
result: OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
);
ARCHITECTURE arch-alu OF alu IS
SIGNAL arith, logic: STD_LOGIC_VECTOR (15 DOWNTO 0);
BEGIN
----rest of the code which give values to arith and logic----
WITH operation SELECT
result <= arith WHEN (1 TO 5),
logic WHEN (6 TO 10);
END arch-alu
My query is: Can I put a range after WHEN (as in the code), or I have to specify one by one each possibility of the signal.
Thanks!
According to http://tams-www.informatik.uni-hamburg.de/vhdl/tools/grammar/vhdl93-bnf.html the syntax you've used is permitted by VHDL '93 (the productions to look at there, in order: selected_signal_assignment, selected_waveforms, choices, choice, discrete_range, range) except that the grammar there doesn't seem to allow for the parentheses around the ranges. See also http://www.vhdl.renerta.com/source/vhd00063.htm (which again has no parens around the ranges).
You can use ranges in choices but you should omit the parentheses.
Not that your code fragment contained a lot more errors than just the superfluous parentheses. You had a missing end entity, a superfluous semicolon at the end of the port declaration, and incorrect integer port declaration,... A good VHDL IDE, such as Sigasi HDT, would help you catch these immediately.
Corrected fragment:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY alu IS
PORT (a: IN STD_LOGIC_VECTOR (15 DOWNTO 0);
b: IN STD_LOGIC_VECTOR (15 DOWNTO 0);
operation: IN INTEGER range 1 TO 10;
result: OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
);
end entity;
ARCHITECTURE arch_alu OF alu IS
SIGNAL arith, logic: STD_LOGIC_VECTOR (15 DOWNTO 0);
BEGIN
--rest of the code which give values to arith and logic----
WITH operation SELECT
result <= arith WHEN 1 TO 5,
logic WHEN 6 TO 10;
END arch_alu;

Resources