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.
Related
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.
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.
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.
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.
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.