VHDL - library doesn't work - iis

I've create a new project on Quartus II with VHDL, but after I run it give me the errors shown below. Do you have any idea why?
Error (10481): VHDL Use Clause error at test_VHDL.vhd(5): design library "work" does not contain primary unit "std_arith"
Error (10800): VHDL error at test_VHDL.vhd(5): selected name in use clause is not an expanded name
Error: Quartus II 64-Bit Analysis & Synthesis was unsuccessful. 2 errors, 1 warning
Error: Peak virtual memory: 1003 megabytes
Error: Processing ended: Sat Dec 5 19:50:39 2015
Error: Elapsed time: 00:00:13
Error: Total CPU time (on all processors): 00:00:38
Error (293001): Quartus II Full Compilation was unsuccessful. 4 errors, 1 warning
Here is my code:
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.std_arith.all; --extinde operatorul ” + “ la opera]ii \ntre semnale
--[i numere \ntregi
entity SUM is
port (a : in std_logic_vector(3 downto 0);
b : in std_logic;
ini,start,clk,a_disponibil,b_disponibil : in std_logic;
sum : out std_logic_vector(4 downto 0);
q : inout std_logic_vector(4 downto 0));
end SUM;
architecture arch_SUM of SUM is
signal load_a,load_b,reset,load_s : std_logic;
signal z : std_logic_vector(0 to 3);
type STARE is (S0,S1,S2,S3,S4); --st`rile automatului
signal S : STARE;
begin
--NUMARATOR
---------------------------------------------------------------
NUM : process(b)
begin
if rising_edge(b) then
if reset='1' then q<=(others=>'0');
elsif load_a='1' then
for i in 3 downto 0 loop --\ncarc` operandul a
q(i) <= a(i); --\n ultimii 3 bistabili
end loop; --ai num`r`torului
elsif load_b='1' then
q <= q+1; --adun` b la a
end if;
end if;
end process NUM;
--REGISTRU
--------------------------------------------------------------------
REG: process(clk)
begin
if rising_edge(clk) then
if reset='1' then sum<=(others=>'0');
elsif load_s='1' then
sum<=q;
end if;
end if;
end process REG;
--AUTOMAT
-----------------------------------------------------------------------------------
AUTOMAT : process(ini,clk)
begin
if INI='1' then s<=S0; --ini]ializeaz` automatul
elsif rising_edge(clk) then
case S is --descrie diagrama st`rilor
when S0 =>
if start='1' then S<=S1;
else S<=S0;
end if;
when S1 =>
if a_disponibil='1' then S<=S2;
else S<=S1;
end if;
when S2 =>
if b_disponibil='1' then S<=S3;
else S<=S2;
end if;
when S3 =>
if b_disponibil='0' then S<=S4;
else S<=S3;
end if;
when S4 => S<=S0;
end case;
end if;
end process AUTOMAT;
with S select
z<= "0000" when S0, --genereaz` ie[irea
"0010" when S1,
"1000" when S2,
"0100" when S3,
"0001" when others;
load_a <= z(0);
load_b <= z(1); --conexiuni interne
reset <= z(2);
load_s <= z(3);
end arch_SUM;
Have anyone idea why and how can solve it?

The statement use work.std_arith.all; introduces the sysnthesis compiler to look for a package std_arith in the same library as of the VHDL file. If you didn't specify one in the Quartus project settings, that it will be the default library. In this case, you have to provide your own implementation of the package and to add this file to the Quartus project as well.
If you are looking for the non-standard package from Synopsys, then you must change the line to use ieee.std_logic_arith.all;. But, this library does not define an operator + for the type std_logic_vector. EDIT The required operator is defined in the package std_logic_unsigned, if you want to treat your std_logic_vectors as unsigned numbers. The package is included with use ieee.std_logic_unsigned.all;. If you want signed arithmetic instead, then include use ieee.std_logic_signed.all;.
But, I recommend to use the standard IEEE library ieee.numeric_std instead, which defines arithmetic operators on the vector-types unsigned and signed.
For example, declare in the entity
sum : out unsigned(4 downto 0);
q : inout unsigned(4 downto 0);

Related

vhdl-fsm with timer- clock cycle delay

i have to write in vhdl an FSM with timer.
I think that,there is no need you to get tired of understanding what my circuit will do.
I just wanted to help me with this:
Every change from a state to another state, there is one (or more) clock cycle delay.
The question is, how can i avoid it?
my vhdl code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
entity fsm_timers is
port( x: in bit;
clk, rst: in std_logic;
y: out bit);
end fsm_timers;
architecture Behavioral of fsm_timers is
constant T1: std_logic_vector(7 downto 0) :="00000011";
constant T2: std_logic_vector(7 downto 0) :="00000111";
signal t: std_logic_vector(7 downto 0) := (others=>'0');
signal rst_cnt: std_logic :='0';
Type state is (A,B,C);
signal pr_state, nx_state : state := A;
component counter is
port(reset,clock, inner_rst:in std_logic;
cnt:out std_logic_vector(7 downto 0));
end component;
begin
U_sum_counter: counter port map(
reset => rst,
inner_rst => rst_cnt,
clock => clk,
cnt => t);
process(clk,rst)
begin
if (rst='1') then
pr_state<= A;
elsif (rising_edge(clk)) then
pr_state<=nx_state;
end if;
end process;
process(x,t,pr_state)
begin
case pr_state is
when A =>
y<='0';
rst_cnt<='1';
if (x='1') then
nx_state<= B;
else
nx_state<= A;
end if;
when B =>
y<='0';
rst_cnt<='0';
if (x='0' and t=(T1-1)) then
nx_state<= C;
end if;
if ((x='0' and t<(T1-1)) or (x/='0' and t<(T2-1))) then
nx_state<= B;
end if;
if (t=(T2-1)) then
nx_state<= A;
end if;
when C =>
y<='1';
rst_cnt<='0';
if (t=(T2-1)) then
nx_state<= A;
else
nx_state<= C;
end if;
end case;
end process;
end Behavioral;
Thank you in advance
I think you can't avoid at least a single clock delay. The reason is that you have to remember your current state. For saving the state you have to use a register, which will cause the delay. Otherwise you can avoid this by using an asynchronous state machine, but then you will have to be careful about your input.
A usual Moore's state machine has:
\/-------------|
input --> transition logic --> state memory --> output logic --> output
^-clk ^-rst ^-enable
This structure can be nicely expressed by 3 processes. For trying to reduce the latency, you can connect the output logic directly to the transition logic, but you might need a register after that anyway.
For details see this page i googled, it is pretty detailed.

How to use two switches in vhdl

I want to control the value of a variable using two switches. One for incrementing the value, whereas the other one for decrementing the value. How should i shange this code.
error says that the variable counting is unsynthesisable.
I have tried a lot but could not figure out what exactly the problem is.
ERROR:Xst:827 - line 34: Signal counting0 cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release.
library IEEE;
use IEEE.std_logic_1164.ALL;
use IEEE.numeric_std.ALL;
entity counts is
port(
btn_up : in std_logic;
reset : IN STD_LOGIC;
btn_dn : in std_logic;
counted : out std_logic_vector(8 downto 0)
);
end entity counts;
architecture behaviour of counts is
signal counter : std_logic_vector(8 downto 0);
begin
btupprocess : process(btn_up,reset,counter)
variable counting : unsigned(8 downto 0);
begin
counting := unsigned(counter);
if(reset = '1') then
counting := (others => '0');
elsif (rising_edge(btn_up)) then
if(counting > 399) then
counting := counting - 1;
else
counting := counting + 1;
end if;
end if;
counter <= std_logic_vector(counting);
end process;
btndnprocess : process(btn_dn,counter)
variable counting : unsigned(8 downto 0);
begin
counting := unsigned(counter);
if (falling_edge(btn_dn)) then
if(counting < 200) then
counting := counting + 1;
else
counting := counting - 1;
end if;
end if;
counter <= std_logic_vector(counting);
end process;
counted <= counter;
end behaviour;
Although in some cases it is possible to drive a signal from two different processes, there are better approaches in this case.
A possible solution to your problem is:
add a clock input to your entity; you should probably use a synchronous design
rewrite your architecture to use three processes, with each process driving a single signal:
one process will debounce and detect a rising edge on btn_up; this process will generate the signal btn_up_rising_edge
one process will debounce and detect a rising edge on btn_dn; this process will generate the signal btn_dn_rising_edge
a third process will read btn_up_rising_edge and btn_dn_rising_edge, and increment or decrement the count as appropriate
in all three processes, your sensitiviy list should contain clock and reset only
You can find an example of an edge detector with a debouncer here: https://electronics.stackexchange.com/questions/32260/vhdl-debouncer-circuit

VHDL - Making a clock from another module's output signal

I am modifying a simple keyboard interface I found on the net to my use. The idea is whenever there is a new scancode, it will make the output named "Scan_Dav" go high, and then go low. So when I direct Scan_Dav to another module as a clock, that module's clock will have a rising edge whenever a new ScanCode is pressed. Is there any error in my way of thinking? Because I tried it and directed the scancode and scan_dav to the rest of my project -which writes letters side by side with the given scancodes and shows them on seven segment display- the displayed text had 2 of each character ( i.e. when I write FLY the text was like FFLLYY). If there is no errors, I will share my code and ask you why it is not working. Thanks :)
EDIT: This is where the shifting is done according to values of Scan_Dav
signal bytes : std_logic_vector(63 downto 0);
signal Scan_Dav_Sync: std_logic_vector(1 downto 0):="00";
signal Previous_Scan_Dav: std_logic:='0';
begin
process (clk) begin --, Scan_Dav) begin
if rising_edge(clk) then
Scan_Dav_Sync(0) <= Scan_Dav;
Scan_Dav_Sync(1) <= Scan_Dav_Sync(0);
Previous_Scan_Dav <= Scan_Dav_Sync(1);
if (Previous_Scan_Dav = '0') and (Scan_Dav_Sync(1) = '1') then
bytes <= bytes (bytes'high-8 downto 0) & Data_in;
end if;
end if;
end process;
This is where Scan_Dav comes from, the code is taken from here:
(You may ignore the filtering part)
Architecture Behavioral of KeyboardController is
signal PS2_Datr : std_logic;
subtype Filter_t is std_logic_vector(7 downto 0);
signal Filter : Filter_t;
signal Fall_Clk : std_logic;
signal Bit_Cnt : unsigned (3 downto 0);
signal Scan_DAVi : std_logic;
signal S_Reg : std_logic_vector(8 downto 0);
signal PS2_Clk_f : std_logic;
Type State_t is (Idle, Shifting);
signal State : State_t;
signal Scan_Code : std_logic_vector(7 downto 0);
signal Flag : std_logic:='0';
begin
process (Clk,Reset)
begin
if Reset='1' then
PS2_Datr <= '0';
PS2_Clk_f <= '0';
Filter <= (others=>'0');
Fall_Clk <= '0';
elsif rising_edge (Clk) then
PS2_Datr <= PS2_Data and PS2_Data; -- also turns 'H' into '1'
Fall_Clk <= '0';
Filter <= (PS2_Clk and PS2_CLK) & Filter(Filter'high downto 1);
if Filter = Filter_t'(others=>'1') then
PS2_Clk_f <= '1';
elsif Filter = Filter_t'(others=>'0') then
PS2_Clk_f <= '0';
if PS2_Clk_f = '1' then
Fall_Clk <= '1';
end if;
end if;
end if;
end process;
-- This simple State Machine reads in the Serial Data
-- coming from the PS/2 peripheral.
process(Clk,Reset)
begin
if Reset='1' then
State <= Idle;
Bit_Cnt <= (others => '0');
S_Reg <= (others => '0');
Scan_Code <= (others => '0');
Scan_Out <= (others => '0');
Scan_Davi <= '0';
elsif rising_edge (Clk) then
-- if Scan_Davi = '1' then
-- Scan_Davi <= '0';
-- end if;
case State is
when Idle =>
Bit_Cnt <= (others => '0');
-- note that we dont need to clear the Shift Register
if Fall_Clk='1' and PS2_Datr='0' then -- Start bit
State <= Shifting;
end if;
when Shifting =>
if Bit_Cnt >= 9 then
if Fall_Clk='1' then -- Stop Bit
Scan_Code <= S_Reg(7 downto 0);
if (Flag = '1' and Scan_Code /= "11110000") then
--to ignore makecode
Scan_Out <= Scan_Code;
Flag <= '0';
Scan_Davi <= '1';
end if;
if (Flag = '0' and Scan_Code = "11110000") then
--to ignore F0
Flag <= '1';
Scan_Davi <= '0';
end if;
State <= Idle;
end if;
elsif Fall_Clk='1' then
Bit_Cnt <= Bit_Cnt + 1;
S_Reg <= PS2_Datr & S_Reg (S_Reg'high downto 1); -- Shift right
end if;
when others => -- never reached
State <= Idle;
end case;
end if;
end process;
Scan_DAV <= Scan_DAVi;
end Behavioral;
UPDATE: The only problem that remains is the delayed display and shifting of the letter and the text. While writing VHDL, I get nothing after pressing V, then I get V when I press H and it goes like that. The last letter does not appear until another key is pressed.It seems to be an issue about Scan_Dav, yet I can not resolve what it is. Any help will be appreciated.
Driving a clock input from logic output is generally bad practice (and some FPGA fabrics will not allow it at all). Clocks run best when sourced from dedicated clock logic inside the part, and good designs should minimize the number of clocks. Ideally you'd have only one, but that's not always possible.
Instead of running a clock input from logic, consider running everything off of one clock and use "enables" to activate the logic only when needed. In this case, you would detect the rising-edge transition of scan_dav inside of the downstream module and only react when that transition occurs. The detection logic would run off of the same clock as the scan_dav module.
I don't think this explains why you're seeing double characters, you would need to post some code to analyze. However, I would recommend that you re-tool to not drive clocks from logic.
If I see it right you avoid the F0 when you release the Key but you do not filter the second scancode.
It's always like this
Scancode --- press Key
F0 --- relesase Key
Scancode
on some Keys (e.g ALT GR) you can get an E0 too.
It not complete description but the most importand thinks are shown.
http://en.wikipedia.org/wiki/Scancode
This would lead to the descripted problem. FLY -> FFLLYY.

VHDL - Scrolling Text on 7 segment Display

I am near to end in my project but stuck at some point. I can not resolve the problem
After deciding VHDL is having a hard time shifting indexes of arrays, I decided to change my shifter module. Now it is properly compiling and the RTL schematic seems true, but unfortunately I used a rather non-innovative way to shift the scancodes.
I defined an 64bit std_logic_vector that can hold up to 8 scancodes, and then parsed the 4 MSBmost bytes of this vector, and directed them to seven segment controller, that muxes the inputs and decides which seven segment will be enabled. I am thinking that I have problems with clock, but seeing nothing on the display makes me think some part of the device is malfunctioning. I am sure my keyboard controller works fine, as I tried it outindividually, shifter looks fine as well( I also tried this one on FPGA but without slowing the clock down, but nevertheless I was able to see the last scancode I entered), I haven't thought of any way/method to try out 7 segment controller, but that seems fine too. I don't know what the problem is, the text is not scrolling :(
Shifter.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.numeric_std.all;
entity my_shifter is
port(clk : in std_logic;
Scan_Dav : in std_logic;
Data_in : in std_logic_vector (7 downto 0);
O1 : out std_logic_vector(7 downto 0);
O2 : out std_logic_vector(7 downto 0);
O3 : out std_logic_vector(7 downto 0);
O4 : out std_logic_vector(7 downto 0)
);
end my_shifter;
architecture bhv of my_shifter is
signal bytes : std_logic_vector(63 downto 0);
begin
process (clk) begin
if rising_edge(clk) then
if Scan_Dav = '1' then
bytes <= bytes (bytes'high-8 downto 0) & Data_in;
end if;
end if;
end process;
O1 <= bytes(63 downto 56);
O2 <= bytes(55 downto 48);
O3 <= bytes(47 downto 40);
O4 <= bytes(39 downto 32);
end bhv;
clkdivide.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity clkdivide is
Port (clkin: in std_logic;
clkout:out std_logic );
end clkdivide;
architecture Behavioral of clkdivide is
signal int_clock:std_logic;
begin
clkout<=int_clock;
process(clkin)
variable var:integer range 0 to 12500 :=0;
begin
if (clkin'event and clkin = '1') then
if var = 12500 then
int_clock <= not int_clock;
var:=0;
else
var:=var+1;
end if;
end if;
end process;
end Behavioral;
SevenSegmentControl.vhd:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
entity SevenSegmentController is
port (
CLK: in std_logic;
DEC1, DEC2, DEC3, DEC4: in std_logic_vector(7 downto 0);
SEGMENTS: out std_logic_vector(6 downto 0);
ANODES: out std_logic_vector(3 downto 0)
);
end SevenSegmentController;
architecture Behavioral of SevenSegmentController is
signal DecoderInput: std_logic_vector(7 downto 0);
signal CurrentDisplay: std_logic_vector(1 downto 0) := "00";
signal Prescaler: std_logic_vector(15 downto 0) := (others => '0');
begin
Multiplex: process(CLK)
begin
if rising_edge(CLK) then
if Prescaler(15) = '0' then
Prescaler <= Prescaler + 1;
else
CurrentDisplay <= CurrentDisplay + 1;
Prescaler <= (others => '0');
end if;
end if;
end process Multiplex;
SevenSegmentDecoder: entity work.SevenSegment_Decoder(Behavioral)
generic map ( INVERT_OUTPUT => '1' )
port map ( number => DecoderInput, segment => SEGMENTS );
DecoderInput <= DEC1 when CurrentDisplay = "00" else
DEC2 when CurrentDisplay = "01" else
DEC3 when CurrentDisplay = "10" else
DEC4 when CurrentDisplay = "11";
ANODES <= "0111" when CurrentDisplay = "00" else
"1011" when CurrentDisplay = "01" else
"1101" when CurrentDisplay = "10" else
"1110" when CurrentDisplay = "11";
end Behavioral;
We have no idea of the interface protocol of SevenSegment_Decoder, but it does look funny that you only have two inputs, but no clock. How does the decoder know when to interpret the signals?
"I haven't thought of any way/method to try out 7 segment controller"
Unless you are using a VERY old version of ISE, certainly older than ISE10, it has a fairly decent simulator (ISIM) built in. (ISIM goes back further than ISE10, but it wasn't really usable and even ISIM 10 had its problems...)
You would save a lot of time if you wrote a simple testbench and unit-tested these modules as you went along.

Delay a signal in vhdl

I would like to delay a signal several cycles in vhdl, but I have problems using how to delay a signal for several cycles in vhdl
Wouldn't I need a registered signal? I mean, something like:
a_store and a_store_registered would be std_logic_vector(cycles_delayed-1 downto 0)
process(clk)
begin
if rising_edge(clk) then
a_store_registered <= a_store;
end if;
end process;
a_out <= a_store_registered(cycles_delayed-1);
process(a_store_registered, a)
begin
a_store <= a_store_registered(size-2 downto 0) & a;
end process;
The solution you link to is a registered signal - the very act of writing to a signal inside a process with a rising_edge(clk) qualifier creates registers.
An even simpler implementation of a delay-line can be had in one line of code (+ another one if you want to copy the high bit to an output)
a_store <= (a_store(a_store'high-1 downto 0) & a) when rising_edge(clk);
a_out <= a_store(a_store'high);
Not sure why I didn't mention this in my answer to the linked question!
I am not sure why you are approaching the problem as you are; there is no need for a second process here. What is wrong with the method suggested in the linked question?
if rising_edge(clk) then
a_store <= a_store(store'high-1 downto 0) & a;
a_out <= a_store(a_store'high);
end if;
In this case your input is a and your output is a_out. If you want to make the delay longer, increase the size of a_store by resizing the signal declaration.
If you want to access the intermediate signal for other reasons, you could do this:
a_store <= a_store_registered(cycles_delayed-2 downto 0) & a;
process(clk)
begin
if rising_edge(clk) then
a_store_registered <= a_store;
end if;
end process;
a_out <= a_store_registered(cycles_delayed-1);
Remember that you can use the foo'delayed(N ns) attribute or foo <= sig after N ns in simulations.

Resources