VHDL inout ports - vhdl

I am having trouble creating an entity using inout ports. I tried writing the following code where A is an input and B is an output and it works fine. But as soon as I change A to an inout port, it implements but it won't simulate. Can anyone tell me what the problem is?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Problem2 is
Port ( A : inout integer;
B : out integer
);
end Problem2;
architecture Behavioral of Problem2 is
procedure change (signal A: inout integer; signal B: out integer) is
begin
B<=A after 20 ns;
end change;
begin
change(A=>A, B=>B);
end Behavioral;

The procedure "change" is a driver on A, but doesn't explicitly drive anything, so A will be driven to 'U'. Try this change which should do what you seem to expect:
procedure change (signal A: inout integer; signal B: out integer) is
begin
A <= 'Z';
B <= A after 20 ns;
end change;

Usually, you don't need inout ports. Especially if you are just starting to use VHDL, stick with in or out. Inout is used for modeling tri-state busses. As #wjl points out, you need to assign 'Z' to the signal if you want to be able to read what the other side is writing.
Also, if you are writing procedures for your later reuse, you should not wrap them in an entity and then test the entity. This just causes extra problems (as you are experiencing right now). Instead, call the procedure directly from your test bench, like you would test a procedure (or function) in software.

Are you using Synopsys VCS ?
There is a known limitation in VCS that inout(s) in the entity do not simulate (show up as red)

Related

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.

VHDL - why do we need to declare signals for processes?

Just revisiting some VHDL and I was wondering inside processes for example, why do we need to declare a signal for a clock for example? Then later on in the code assign it to the port from the entity...
EXAMPLE VHDL:
signal clk_int: std_logic := '1';
BEGIN
clkgen: process(clk_int)
begin
clk_int <= not clk_int after 50ns
end process ckgen
ck_l <= clk_int;
In this example ck_l is a physcial port from the d flip flop yet we create and mess around with clk int then return the value to ck
The reason is that the port ck_l in this case is probably declared with direction out, so It cannot be read from. If you want to read it, like you would need to if you want to have a process that is sensitive to it, you need to use a signal or declare the port as inout or buffer.

How to place component parts on RAM on chip

I am making some kind of cache and i am using some tables (big ones) inside entity which are composed of std_logic_vectors and i am doing it in Quartus 2 web edition.
Everything works fine in simulation, but when i try to synthesize it its being done ONLY with latches, AND and OR components.
Is there any way to specify Quartus to use memory modules for those tables instead of these combination elements? Or maybe something can be done from VHDL code itself.
library ieee;
use ieee.std_logic_1164.all;
package UTIL_PACK is
type matrix16x8 is array (0 to 15) of std_logic_vector(0 to 7);
type matrix2p4x8 is array (0 to 2**4) of matrix16x8;
end package;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.util_pack.all;
entity RAM16B is
port(
signal RD: in std_logic;
signal WR: in std_logic;
signal CLK: in std_logic;
signal A: in std_logic_vector(7 downto 0);
signal D: inout matrix16x8;
signal FC: out std_logic
);
end entity ;
architecture RAM16B_IMPL of RAM16B is
signal memory: matrix2p4x8 := ((others => (others => (others => 'Z'))));
begin
run:process(clk)is
variable slot:integer range 0 to 15 :=0;
begin
if(clk='1') then
slot := TO_INTEGER(unsigned(A)) rem 16;
if(rd = '1')then
FC<='0';
for i in 0 to 3 loop
D(i) <= memory(i)(slot);
end loop;
FC<='1';
elsif(wr = '1')then
FC<='0';
for i in 0 to 3 loop
memory(i)(slot) <= D(i);
end loop;
FC<='1';
else
FC <= 'Z';
D <= ( others => ( others => 'Z' ));
end if;
else
FC <= 'Z';
D <= ( others => ( others => 'Z' ));
end if;
end process;
end architecture RAM16B_IMPL;
RAM consists of 16 blocks of memory, each block is 16 bytes. I am trying to read more data parallely so I am reading/writing 16 bytes of data per cycle. Slot defines block in which reading/writing is being done.
If you really want to make sure you use the hard memory blocks, you should either use the mega-function wizard to craft a custom ram component, or directly instantiate an altsyncram component from the library and use the generics to configure it how you want (this can be tricky if you're not extremely familiar with the options). This causes porting issues, but any time you infer ram you generally have porting issues anyway. Using a custom library component just makes it very obvious and easy to identify where you might have problems if you ever do need to migrate to something else.
As for your specific implementation, there's no way you're going to get latches automatically migrated into the hard ram blocks which are edge driven devices. Use rising_edge(clk) instead of clk='1' in your process to fix this.
Also, there is no support for tri-state operation internal to the chip, you need independent data in and data out ports. You are getting lots of discrete logic because and & or gates are being used to emulate a tri-state bus (and because of the latch issue, above).
Yes, you can do it from your VHDL code. To make sure that Quartus understands that you are modeling a memory, you should code it as described in Altera's Recommended HDL Coding Styles guide. Take a look at the section called Inferring Memory Functions from HDL Code (http://www.altera.com/literature/hb/qts/qts_qii51007.pdf), then modify your code accordingly.
It is probably a good idea to start with the exact memory model suggested by Altera, and making sure that Quartus synthesizes the design using the FPGA's dedicated memory bits. Next, you can gradually change your model to implement the desired behavior, always synthesizing and looking at the compilation reports to make sure your changes didn't deviate from what Quartus infers as a memory block.

Error : Identifier 'q' is not readable in architecture of T Flip Flop

I am trying to model a T Flip Flop using VHDL.
library ieee;
use ieee.std_logic_1164.all;
entity tff is
port (
clk: std_logic;
t: in bit;
q: out bit;
qbar: out bit);
end tff;
architecture tff_arch of tff is
begin
process(clk)
begin
if (clk = '1' and t = '1')
then
q <= not q;
qbar <= not qbar;
end if;
end process;
end tff_arch;
But the error i am getting is
Error: CSVHDL0168: tff.vhdl: (line 17): Identifier 'q' is not readable
Error: CSVHDL0168: tff.vhdl: (line 18): Identifier 'qbar' is not readable
The reason of error i think is, i am using "not q", when q has not been initialized. Correct me here, if i am wrong.
And what to do to get around this problem? I have modeled D Flip flop and its test bench waveform correctly using Symphony EDA free version.
In the old days you couldn't read an output, so you had to either:
make it an inout (which is a bit unpleasant as you are fudging the direction you really mean, just so you can read it) - this works, but is not widely used in industry (as far as I'm aware)
make it a buffer, but that had downsides (prior to VHDL-2002) in that you have to make all the rest of the hierarchy of that signal driven by buffers. Almost never used in my experience.
use and intermediate signal (which you can read) and then use an assignment to set the output to the value of that signal. This is the idiomatic way of doing it amongst practising engineers.
Since VHDL-2008 you can read output ports (although the stated intention of this is for it only to be used for verification purposes). You'll probably need a tool switch to enable VHDL-2008 mode. (And it may be that your particular simulator/synthesiser still doesn't support VHDL-2008, which shows the staggering pace of development in the EDA tools world!)
q is an output of the entity.
You can't read an output. It's that simple.
You need an internal version that you use for the feedback loop, and then q <= local_q;
Can't remember VHDL very well, but this might give you a clue:
The problem is that q is only a signal out of your entity, so there is nothing to access when you try to read it.
So, to not solve your homework, think of it this way:
Either you need to have q as an input in order to access it (probably not what you want) or you need to store q (or at least next value of q) internally. This can be done by specifying q (or q_next) as a signal in the architecture part. For example:
architecture tff_arch of tff is
signal q_next: std_logic;
begin
and so on. The same goes for your qbar signal.

Resources