VHDL: Concat inout std_logic into std_logic_vector signal - vhdl

I have several tri-stateable (inout) std_logic port pins defined in my top-level port declaration. I have a dedicated internal component that is needing to utilize these, but its port is defined as having an inout std_logic_vector (not my code and I can't change), which I need to concatenate my std_logic into a std_logic_vector to make it happy.
The problem is: I'm not sure how to do this.
I thought that ALIAS would be the correct route, but apparently the concatenation operator can't be used when defining an alias.
Then I thought I'd just use a std_logic_vector internal signal:
mySignal <= inOutBit2 & inOutBit1 & inOutBit0; --Input route
componentPort => mySignal, --Component use
inOutBit2 <= mySignal(2);
inOutBit1 <= mySignal(1);
inOutBit0 <= mySignal(0); --Output route
but this would not synthesize as it viewed inOutBitn as having multiple drivers.
Is there anything I can do to get this to synthesize? I know I can just declare my top-level inout port to be a std_logic_vector, but that is sub-optimal as we have a a well defined port-labeling convention.

Based on your description, I understand that both the top-level ports and the component ports are mode inout.
If this is so, then it may help if you connect the component ports directly to the external inout ports at std_logic level, like:
componentPort(0) => inOutBit0, --Component use
componentPort(1) => inOutBit1, --Component use
componentPort(2) => inOutBit2, --Component use
The intermediate mySignal is then not required.
However, the description says that synthesis reports multiple drivers for inOutBitn, but I would expect that it reported multiple drivers for mySignal in the original code.

Related

Difference between declaring signal in architecture and in entity

Assuming that I have the following piece of code:
entity MyEntity is
port (
i_clock : in std_logic; -- these are the signals inside entity
Clk_100HZ : inout std_logic;
Data : inout std_logic;
);
end MyEntity;
architecture rtl of MyEntity is
signal D_zeroin : std_logic; -- these are the signals inside architecture
signal D_onein : std_logic;
signal D_twoin : std_logic;
signal D_threein : std_logic;
begin
...
What is the difference between signals declared in port's entity and signals declared directly into architecture?
Declarations in the entity can be of ports or generics. Generics are constants fixed at compilation time. Ports input and/or output signals from the architecture to the instantiating architecture i.e. the 'next level up'.
Signals are nodes/registers/memory within the architecture itself that cannot be seen by any architectures outside.
The parallel often given is that of a logic chip IC on a circuit board:
The entity specifies the pins on the IC that signals flow through, in and out of the chip to the board.
The architecture is the chip circuit inside the IC package. Its internals cannot be accessed.
Instantiating a component is plugging one of that IC into a circuit board.
The publicly-known entity will be visible to the architecture above that instantiated that component.
But the architecture is hidden away with its contents not visible to any other part of the design and not necessarily visible to the people using the component. Different architectures can be designed and associated with the entity for compilation.

VHDL buffer variable vs out variable

I work in a VHDL program and I need to do a RAM 256 using the ALTERA DE2-115. The outputs will show in a seven segment display.
The problem is that: I have a dataout output variable. Then the variable has the following values of the temp_ram array:
dataout <= temp_ram(conv_integer(dir));
Then I want to divide the vaules of dataout to put in the seven segment
dataout(7 downto 4)
dataout(3 downto 0)
This shows the following error:
Error (10309): VHDL Interface Declaration error in RAM.vhd(45): interface object "dataout" of mode out cannot be read. Change object mode to buffer.
When I change to buffer and this run prefect, but I can't understand what happen
For cross-platform compatibility and code-reusability, I'd recommend an intermediate signal ( dataout_int can be used by other statements) :
dataout_int <= temp_ram(conv_integer(dir));
and assign the output to this intermediate signal:
dataout <= dataout_int;
You are using conv_integer from a Synopsys package. Please use only official IEEE packages.
dataout is a signal, not a variable, because you use a signal assignment statement. Moreover, the signal is a port of mode out. (Ports are signals as well).
Besides static typing, VHDL is also checking directions of signal in ports. Your signal is of mode out so it can't be read.
Als a solution, you can:
use an intermediate signal,
use mode buffer, which is not supported by all synthesis tools equally
use VHDL-2008, which allows ports of mode out to be read.
Quartus support some VHDL-2008 features.

Can't handle registered multi driver

I am getting this messege from compiler for all the "busreg" bits:
topld: busshift.vhd: (E463) 'busreg(7)' -- Can't handle registered multi driver.
topld: busshift.vhd: (E446) Can't handle multiple drivers for 'busreg(7)' in selected device.
I was asked to do shift rigister that I can put in put from both side as I choose depends on DIR.
My code:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.std_logic_arith.all;
ENTITY shiftbus IS
PORT
(
busreg : inout std_logic_vector(7 downto 0);
dir,clk : IN std_logic;
pinL,pinR : inout std_logic
);
END shiftbus;
ARCHITECTURE behavioral OF shiftbus IS
BEGIN
busreg<="00000000";
process(clk,dir)
begin
if (rising_edge(clk)) then
if(dir='1') then --1 we input from right
busreg<=busreg(6 downto 0)&pinR;
else-- else is 0 and we input from left
busreg<=pinL & busreg(7 downto 1);
end if;
end if;
end process;
END behavioral;
You have the following line:
busreg <= "00000000";
If you're going to drive this signal low all the time, what's the point of the other logic?
You are driving the signal busreg from two processes: the explicit process and the implicit process busreg <= "00000000";. In other words, you have a short circuit.
A process is a little bit of software that models a little bit of hardware.
So, when you drive a signal from more than one process, you are modelling a signal that is driven from more than one lump of hardware. Normally, if you want to drive a signal from two or more lumps of hardware, you need to be using tristate logic. I think the error message is telling you that the FPGA device you have chosen is not able to implement tristate logic and so it is an error for you to drive a signal from more that one place.
So, why have you written the line busreg <= "00000000";? If you were hoping to reset your shift register, you haven't; you've created a short circuit.
BTW: your process is a sequential process. The sensitivity list of a sequential process should either contain just the clock or, if there is an asynchronous reset, just the clock and the asynchronous reset. dir should not be in your sensitivity list.

Write an inout Port in a testbench

I am currently working on a project where I want to implement a bidirectional bus. For this project I was given an entity that I should not edit.
This entity has two inout ports (sda and scl).
I now want to write from the TestBench to the entity through the inout port sda. To do this I assign a value to to the signal that is connected to sda.
When I do this, I get the error that I have multiple sources for the unresolved signal sda. One is the assigned value and one is the entity itself.
I do not understand how I can assign a value to this inout port without triggering this error.
Is there a quick explanation for this problem ? Otherwise what buzzwords are useful for searching a solution to this problem ?
My code for this:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity i2c_slave_tb is
end i2c_slave_tb;
architecture arch of i2c_slave_tb is
-- signal declaration
-- sim signals
-- uut signals
signal sda: std_ulogic;
signal scl: std_ulogic;
begin -- arch
uut : entity work.i2c_slave
port map (
sda=>sda,
scl=>scl
);
stim_gen :process
begin
wait for 10 ns;
sda<='1';
wait;
end process stim_gen;
end arch;
The sda and scl signals are std_ulogic where the "u" stands for unresolved, meaning that there can be only one driver for the signal, since there is no resolution function attached to the type to determine the signal value in case of multiple drivers.
Change the type to std_logic for a type with standard resolution function, like:
signal sda: std_logic;
signal scl: std_logic;
You can look here for some description of "VHDL resolution function", or search it.

How do User Constraint Files actually work?

I got WebPack up and running on my machine again and after synthesizing a simple design and uploading it to my FPGA, I encountered quite a problem with my understanding.
When there is a line like this in the user constraint file:
NET "W1A<0>" LOC = "P18" ;
How exactly does the synthesis software determine how this pin gets assigned to by the VHDL code?
For instance, take this example code I've been provided with:
entity Webpack_Quickstart is
Port (
W1A : out STD_LOGIC_VECTOR(15 downto 0);
rx : in STD_LOGIC;
tx : inout STD_LOGIC;
clk : in STD_LOGIC
);
end Webpack_Quickstart;
architecture Behavioral of Webpack_Quickstart is
signal counter : STD_LOGIC_VECTOR(47 downto 0) := (others => '0');
begin
W1A(0) <= '1';
end;
How exactly does this code make the WIA0 pin on my FPGA turn on? What is the link? Is it just the name of the port in the entity declaration is there more magic involved?
Your .ucf constraints are applied in the implementation phase. At this point your design has been synthesized, and the available top-level nets are thus "known". So yes, it is only a matter of matching equally named nets to equally named constraints.
The syntax is slightly different though (using <> instead of () for indexing vectors for instance), but otherwise it's just a simple string match.
The easiest way to initially configure your pin constraints, especially for large designs, is to just use one of the graphical tools (PlanAhead, if it's included in the WebPack) to assign the pins, and generate an initial .ucf file.
I find that making small changes later on is easiest to do by hand using the standard ISE text editor directly though.

Resources