My purpose is to impement a Keyboard entity which uses Button entites.
So I wrote the following VHDL code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Keyboard is
port ( ck, stop : in STD_LOGIC;
data_in : in STD_LOGIC_VECTOR (11 downto 0);
data_out : out STD_LOGIC_VECTOR (3 downto 0));
end Keyboard;
entity Button is
port ( clk : in STD_LOGIC ;
signal_in : in STD_LOGIC;
output : out STD_LOGIC);
end Button;
architecture test of Keyboard is
signal NUM : STD_LOGIC_VECTOR (11 downto 0) := (others=>'0');
component Button is
port ( clk : in STD_LOGIC ;
signal_in : in STD_LOGIC;
output : out STD_LOGIC);
end component;
begin
num_0 : entity Button port map(ck,data_in(0),NUM(0));
num_1 : entity Button port map(ck=>clk,data_in(1)=>signal_in,NUM(1)=>output);
num_2 : entity Button port map(ck=>clk,data_in(2)=>signal_in,NUM(2)=>output);
num_3 : entity Button port map(ck=>clk,data_in(3)=>signal_in,NUM(3)=>output);
num_4 : entity Button port map(ck=>clk,data_in(4)=>signal_in,NUM(4)=>output);
num_5 : entity Button port map(ck=>clk,data_in(5)=>signal_in,NUM(5)=>output);
num_6 : entity Button port map(ck=>clk,data_in(6)=>signal_in,NUM(6)=>output);
num_7 : entity Button port map(ck=>clk,data_in(7)=>signal_in,NUM(7)=>output);
num_8 : entity Button port map(ck=>clk,data_in(8)=>signal_in,NUM(8)=>output);
num_9 : entity Button port map(ck=>clk,data_in(9)=>signal_in,NUM(9)=>output);
num_on : entity Button port map(ck=>clk,data_in(10)=>signal_in,NUM(10)=>output);
num_off : entity Button port map(ck=>clk,data_in(11)=>signal_in,NUM(11)=>output);
output <= "0000" when NUM = "000000000001" else --0
"0001" when NUM = "000000000010" else --1
"0010" when NUM = "000000000100" else --2
"0011" when NUM = "000000001000" else --3
"0100" when NUM = "000000010000" else --4
"0101" when NUM = "000000100000" else --5
"0110" when NUM = "000001000000" else --6
"0111" when NUM = "000010000000" else --7
"1000" when NUM = "000100000000" else --8
"1001" when NUM = "001000000000" else --9
"1010" when NUM = "010000000000" else --ON
"1100" when NUM = "100000000000" else --OFF
"1111";
end test;
architecture EdgeDetector of Button is
signal signal_d:STD_LOGIC;
begin
process(clk)
begin
if clk= '1' and clk'event then
signal_d<=signal_in;
end if;
end process;
output<= (not signal_d) and signal_in;
end EdgeDetector;
By starting the compilation on QuartusII I face the following error:
Error (10482): VHDL error at PitAlarm.vhd(11): object "STD_LOGIC" is
used but not declared
But I can't understand what it means with "not declared" ???
Using "direct entity instantiation" you are explicitly binding an entity out of a specific library instead of using "configurations" or some default strategy to find a matching one. So, num_0 : entity Work.Button port map(...); - note the explicit library name (here, Work).
The specific error you find
std_logic not declared
comes from the visibility rules for library clauses.
Button's own entity/arch will normally be in a separate file, separately compiled before compiling the top level.
It would then have its own library/use clauses for the library where std_logic is declared.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
With more than one entity in the same file, this clause only applies to the following entity declaration (and makes it visible o the corresponding architectures).
So you need to repeat these two lines before each entity declaration in the file.
Related
Summary:
I'm trying to make a password system in VHDL with the DE2 Altera board. SW 0 to 7 is the combination lock, LEDR 0 to 7 shows the current code and signal 'code' stores the combination. When the switches match the code you have the option to change the code by holding down KEY(1).
Problem:
The code works as it should, only the starter code is not what's expected. It should be: "01010101" as shown in the signal; but it comes out as "01111111". I suspect the program enters the if-statement on startup, but I don't see how that's possible, seeing as 'code' and SW should't be equal.
What am I missing?
Here is the code:
library IEEE;
use IEEE.std_logic_1164.all;
entity pass_sys is
port(
SW : in std_logic_vector(7 downto 0);
KEY : in std_logic_vector(3 downto 0);
LEDR : out std_logic_vector(17 downto 0);
LEDG : out std_logic_vector(17 downto 0)
);
end pass_sys;
architecture func of pass_sys is
signal code : std_logic_vector(7 downto 0) := "01010101"; --start code
begin
process(SW)
begin
LEDR(7 downto 0)<=code;
if (SW = code) then
LEDG(0)<='1';
LEDG(1)<=not KEY(1);
if (KEY(1) = '0') then
code<=SW;
end if;
else
LEDG(0)<='0';
end if;
end process;
end func;
I assume your problem happens on your board, not in simulation. If I'm wrong, my answer is not the one you expect.
This initialization way is usefull only in simulation :
signal code : std_logic_vector(7 downto 0) := "01010101"; --start code
Synthesis will not consider your initialization value (That's why I discourage you to use this, except in test bench). If you want to initialize a signal, I advice to use a reset.
Notes :
You should put KEY in sensitivity list and put this line out of your process :
LEDR(7 downto 0)<=code;
Your process infers latches, it's not forbidden but you must be careful with this
EDIT : How to add a reset
library IEEE;
use IEEE.std_logic_1164.all;
entity pass_sys is
port(
RST : in std_logic;
SW : in std_logic_vector(7 downto 0);
KEY : in std_logic_vector(3 downto 0);
LEDR : out std_logic_vector(17 downto 0);
LEDG : out std_logic_vector(17 downto 0)
);
end pass_sys;
architecture func of pass_sys is
signal code : std_logic_vector(7 downto 0);
begin
LEDR(7 downto 0)<=code;
process(SW, code, KEY)
begin
if RST = '1' then
LEDG <= (others => '0');
code <= "01010101";
elsif (SW = code) then
LEDG(0)<='1';
LEDG(1)<=not KEY(1);
if (KEY(1) = '0') then
code<=SW;
end if;
else
LEDG(0)<='0';
end if;
end process;
end func;
The pin RST of your component could be connected to an analogic signal of you card (POWER_GOOD, ALIM_ON, DONE, ...) or to a pll_locked signal of a PLL if you use it.
I made my FSM in VHDL and now I want to use the debounce code with port mapping.
Though I have difficulties with the associations. In fact I want to insett the debouncebutton component among the signals that are driving the FSM.
entity myFSM is
Port ( CLK : in STD_LOGIC;
RST : in STD_LOGIC;
IN0 : in STD_LOGIC;
IN1 : in STD_LOGIC;
IN2 : in STD_LOGIC;
LED : out STD_LOGIC_VECTOR (7 downto 0));
end myFSM;
architecture Behavioral of myFSM is
type state is (A, B, C);
signal currentS, nextS: state;
component debouncebutton
Port ( clk : in std_logic; -- connect it to the Clock of the board
rst : in std_logic; -- connect it to the Reset Button of the board
input : in std_logic; -- connect it to the Push Button of the board
output : out std_logic -- connect it to your circuit
);
end component;
begin
myFSM_comb: process (currentS, IN0, IN1, IN2)
begin
case currentS is
when A => LED <= "11111111";
if IN0 = '1' then nextS<=B;
elsif IN1 = '1' then nextS<=C;
else nextS<=A;
end if;
when B => LED <= "11000011";
if IN0 = '1' then nextS<=C;
elsif IN1 = '1' then nextS<=A;
else nextS<=B;
end if;
when C => LED <= "00111100";
if IN0 = '1' then nextS<=A;
elsif IN1 = '1' then nextS<=B;
else nextS<=C;
end if;
end case;
end process;
myFSM_synch: process(CLK,RST)
begin
if (RST='1') then currentS<=A;
elsif (rising_edge(CLK)) then currentS<= nextS;
end if;
end process ;
begin
db0 : debounce
port map
(
clk => CLK,
rst => RST,
input => IN0,
output
end Behavioral;
I marked up your code by renaming IN0 to INP0 in the port declaration, declared a signal in the architecture with the name INO to keep from changing every occurrence of the name, removed an extraneous begin and renamed the instantiated component from debounce to debouncebutton to match the component declaration:
library ieee;
use ieee.std_logic_1164.all;
entity myFSM is
Port ( CLK : in STD_LOGIC;
RST : in STD_LOGIC;
INP0 : in STD_LOGIC; -- name changed
IN1 : in STD_LOGIC;
IN2 : in STD_LOGIC;
LED : out STD_LOGIC_VECTOR (7 downto 0));
end myFSM;
architecture Behavioral of myFSM is
type state is (A, B, C);
signal currentS, nextS: state;
component debouncebutton
Port ( clk : in std_logic; -- connect it to the Clock of the board
rst : in std_logic; -- connect it to the Reset Button of the board
input : in std_logic; -- connect it to the Push Button of the board
output : out std_logic -- connect it to your circuit
);
end component;
signal IN0: std_logic; --- added
begin
myFSM_comb: process (currentS, IN0, IN1, IN2)
begin
case currentS is
when A => LED <= "11111111";
if IN0 = '1' then nextS<=B;
elsif IN1 = '1' then nextS<=C;
else nextS<=A;
end if;
when B => LED <= "11000011";
if IN0 = '1' then nextS<=C;
elsif IN1 = '1' then nextS<=A;
else nextS<=B;
end if;
when C => LED <= "00111100";
if IN0 = '1' then nextS<=A;
elsif IN1 = '1' then nextS<=B;
else nextS<=C;
end if;
end case;
end process;
myFSM_synch: process(CLK,RST)
begin
if (RST='1') then currentS<=A;
elsif (rising_edge(CLK)) then currentS<= nextS;
end if;
end process ;
-- begin -- syntax error you have a begin before process myFSB_comb
db0 : debouncebutton --- was debounce, needs to match component declaration
port map (
clk => CLK,
rst => RST,
input => INP0, -- renamed input port
output=> IN0 -- newly declared signal INO
);
end Behavioral;
This allowed the new input port INP0 to be associated to the formal input on debouncebutton and the formal output to be connected to the newly declared signal IN0.
You could also go to all the trouble of simply declaring a new signal for the output association and changing instances of the name IN0 other than the port declaration for myFSM.
Your modified code above analyzes. Without creating an entity/architecture pair for debouncebutton it can't be elaborated (or simulated).
In this code, when reset equals 1 the s becomes 1000 and when reset equals 0 the s becomes 0100 then 0010 then 0001 and it starts all over again with 1000 as the start value, only if the clock is up.
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity clock_behav is
port (clock : in std_logic;
reset : in std_logic;
s : out std_logic_vector (3 downto 0));
end clock_behav;
architecture behav of clock_behav is
begin
process(clock,reset)
variable shift_counter: integer := 0;
begin
if (reset='1') then
s<="1000";
shift_counter := 1;
else
if(clock'event and clock='1') then
if(shift_counter =1) then
s<="0100";
shift_counter := 2;
elsif(shift_counter =2) then
s<="0010";
shift_counter := 3;
elsif(shift_counter =3) then
s<="0001";
shift_counter := 0;
else
s<="1000";
shift_counter := 1;
end if;
end if;
end if;
end process;
end behav;
I want to create this
With FlipFlops as you can see, one Set and 3 Reset. But, I struggle to move from behavioral into structural, because in VHDL we can't have in process port maps. Of course I tried many things, as you can see below, but it's impossible to recreate it with flipflops if the port maps are not inside the process. As you can clearly understand , my knowledge about VHDL it's not that great. Also, I want you to tell me if I did right when I changed the flipflop D and Q types, it was std_logic and I changed it to std_logic_vector . I did this for the purpose of this exercise.
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity clock_structural is
port (clock : in std_logic;
reset : in std_logic;
s : out std_logic_vector (3 downto 0));
end clock_structural;
architecture behavior of clock_structural is
signal t,t1,t2,t3 : std_logic_vector (3 downto 0);
component flipflop_new
port
(D : in std_logic_vector (3 downto 0);
CLK : in std_logic;
CLR : in std_logic;
Q : out std_logic_vector (3 downto 0));
end component;
component flipflop_set
port
(D_s : in std_logic_vector (3 downto 0);
CLK_s : in std_logic;
CLR_s : in std_logic;
Q_s : out std_logic_vector (3 downto 0));
end component;
begin
process(clock,reset)
variable shift_counter: integer := 0;
begin
if (reset='1') then
t<="1000";
shift_counter := 1;
else
if(clock'event and clock='1') then
if(shift_counter =1) then
shift_counter := 2;
elsif(shift_counter =2) then
shift_counter := 3;
elsif(shift_counter =3) then
shift_counter := 0;
else
shift_counter := 1;
end if;
end if;
end if;
end process;
FFS1: flipflop_set port map(t,clock,reset,t1);
s<=t1;
FFR1: flipflop_new port map(t1,clock, reset,t2);
s<=t2;
FFR2: flipflop_new port map(t2,clock, reset,t3);
s<=t3;
FFR3: flipflop_new port map(t3,clock, reset,s);
end behavior ;
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity flipflop_new is
port ( D : in std_logic_vector (3 downto 0);
CLK : in std_logic;
CLR : in std_logic;
Q : out std_logic_vector (3 downto 0)
);
end flipflop_new;
architecture behavior of flipflop_new is
begin
process(CLK)
begin
if CLR='0' then null;
elsif RISING_EDGE(CLK) then
Q <= D;
end if;
end process ;
end behavior ;
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity flipflop_set is
port ( D_s : in std_logic_vector (3 downto 0);
CLK_s : in std_logic;
CLR_s : in std_logic;
Q_s : out std_logic_vector (3 downto 0)
);
end flipflop_set;
architecture behavior of flipflop_set is
begin
process(CLK_s)
begin
if CLR_s='1' then null;
elsif RISING_EDGE(CLK_s) then
Q_s <= D_s;
end if;
end process ;
end behavior ;
There are several things to change or improve. A structural VHDL model should describe your schematic, which you don't really do.
First, why do you have shift_counter in your structural? You don't need that process.
Second, you instantiate 4 of your flip-flop entity which are each 4 bits wide, while your schematic's has 4 flip-flops. Basically, you instantiate a total of 16 registers when you need 4. Why is your flip-flop model 4 bits wide? It should be a single bit.
Third, look at your flip-flop description:
process(CLK)
begin
if CLR='0' then
null;
elsif RISING_EDGE(CLK) then
Q <= D;
end if;
end process ;
Does it seems what a flip-flop do? The Q <= D when the clock rises is fine, but does nothing happens when the clr of the flip-flop is active? Your output should reset/set in that case, which is not what your VHDL describe.
Another error is that you assign your output s 3 times. s must be assigned once, but you can assign bit individually like s(0) <= t1.
Finally, you don't describe the feedback. The output of your last flip-flop is s, while the input of the first flip-flop is t. From your schematic, they should be connected together.
I am making a circuit that handles read and write operations to some registers and uses a single bus to transfer data between registers, the problem is that when reading from bus (a register is reading from bus) it works well, but when trying to assign a value in a register it is not working. Note that if i used a signal to write to it will work !!!
My Code:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
-- Entity: Circuit
-- Description: Organizes read and write operation to the bus
-- n is the size of word in a register, default is 16
-- m is the number of selection lines in the decoder, so 2 ^ m
-- is the number of registers in the cicuit
-- data_bus: the bus used to transfer data
-- reg_read: input to a decoder determines which register to read from bus.
-- reg_write: input to a decoder determines which register to write to bus.
-- read: read signal
-- write: write signal
-- Clk: clock
-- Rst: Reset
ENTITY circuit IS
GENERIC( n : integer := 16;
m : integer := 2);
PORT(data_bus : INOUT STD_LOGIC_VECTOR(n-1 DOWNTO 0);
reg_read, reg_write : IN STD_LOGIC_VECTOR(m-1 DOWNTO 0);
read, write, Clk, Rst : IN STD_LOGIC);
END circuit;
ARCHITECTURE circuit_arch OF circuit IS
-- Tristate buffers
COMPONENT tsb IS
GENERIC ( n : integer := 16);
PORT ( E : IN STD_LOGIC;
Input : IN STD_LOGIC_VECTOR (n-1 DOWNTO 0);
Output : OUT STD_LOGIC_VECTOR (n-1 DOWNTO 0));
END COMPONENT;
-- Registers
COMPONENT ndff IS
GENERIC ( n : integer := 16);
PORT( Clk,Rst,E : in STD_LOGIC;
d : IN STD_LOGIC_VECTOR(n-1 dOWNTO 0);
output : OUT STD_LOGIC_VECTOR(n-1 dOWNTO 0));
END COMPONENT;
-- Decoders
COMPONENT nDecoder IS
GENERIC ( n : integer := 4);
PORT(E : IN std_logic;
S : IN STD_LOGIC_VECTOR( n-1 DOWNTO 0);
output : OUT std_logic_vector(2 ** n - 1 DOWNTO 0));
END COMPONENT;
TYPE output IS ARRAY (0 TO (2 ** m) - 1) OF STD_LOGIC_VECTOR (n-1 DOWNTO 0);
SIGNAL read_dec, write_dec : STD_LOGIC_VECTOR(2 ** m - 1 DOWNTO 0);
SIGNAL regs_out : output;
SIGNAL test : STD_LOGIC_VECTOR(n-1 downto 0);
BEGIN
-- Generate decoders
dec1: nDecoder GENERIC MAP(m) PORT MAP(read, reg_read, read_dec);
dec2: nDecoder GENERIC MAP(m) PORT MAP(write, reg_write, write_dec);
-- Generate registers
LOOP1: FOR i IN 0 TO (2 ** m) - 1 GENERATE
lbl1: ndff GENERIC MAP(n) PORT MAP(Clk, Rst,read_dec(i),data_bus, regs_out(i));
END GENERATE;
-- Generate tristate buffers
LOOP2: FOR j IN 0 TO (2 ** m) - 1 GENERATE
lbl2: tsb GENERIC MAP(n) PORT MAP(write_dec(j), regs_out(j), data_bus);
END GENERATE;
END circuit_arch;
If you look at lbl1 in the generate statement you'll find the portmap:
lbl1: ndff generic map(n) port map(clk, rst,read_dec(i),data_bus, regs_out(i));
is positionally associative. While the port declaration reflected in the component declaration shows the order:
port( clk,rst,e : in std_logic;
d : in std_logic_vector(n-1 downto 0);
output : out std_logic_vector(n-1 downto 0));
Showing that read_dec(i) is the register load enable.
And the read buffers:
-- generate tristate buffers
loop2: for j in 0 to integer(2 ** m) - 1 generate
lbl2: tsb generic map(n) port map(write_dec(j), regs_out(j), data_bus);
end generate;
Show write_dec(j).
And examining the decodes for generating them shows:
-- generate decoders
dec1: ndecoder generic map(m) port map(read, reg_read, read_dec);
dec2: ndecoder generic map(m) port map(write, reg_write, write_dec);
read corresponds to read_dec and write corresponds to write_dec.
It certainly looks like you have the enables reversed for the registers loads and register output buffer enables.
There could be more, but without a MVCE someone answering can't get beyond basic eyeballing and analyzing.
And the reason Paebbels asked about target implementation is that for all practical purposes tristate internal buffers are generally restricted to ASIC implementations.
I'm currently working on a component that will perform addition or subtraction, depending on the user input. Right now, I am working on a process that handles the assignment of values to the internal signals which will be used by the internal components I am using. One problem that comes up is in the line when I'm assigning b_in with either the input b or the 2's complement of the input b. Two errors show up:
Error: COMP96_0015: addsub_16.vhd : (85, 17): ';' expected.
Error: COMP96_0046: addsub_16.vhd : (85, 41): Sequential statement expected.
The errors all reference to the line
b_in <= (b) when add_sub = '0' else (b_2scomp);
However when I placed this outside the process, no error occurred; only when it's inside the process. Can someone please help me why this is and what I can do to solve it?
In addition, I know that normally port mapping is done between the architecture declaration and the begin statement of the architecture. The reason I placed them after the process is because I needed to make sure that b_in has the right signal before the other components can use it. I don't know if this is the right way to do it, but I hope it is. This is just in case you guys are wondering why I'm dong it like this. Thanks
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.STD_LOGIC_ARITH.all;
entity addsub_16 is
port(
c_in : in STD_LOGIC;
enable : in std_logic;
reset : in std_logic;
clk : in std_logic;
add_sub : in STD_LOGIC;
a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
c_out : out STD_LOGIC;
result : out STD_LOGIC_VECTOR(15 downto 0)
);
end addsub_16;
architecture addsub_16 of addsub_16 is
--Signal declarations to hold internal vectors a, b g, p, and carry
signal a_in : std_logic_vector(15 downto 0); --Holds input a
signal b_in : std_logic_vector(15 downto 0); --Holds input b if add_sub = 0. Otherwise, holds b_2scomp
signal b_2scomp : std_logic_vector(15 downto 0); --Holds the 2s complement of b
signal prop_in : std_logic_vector(15 downto 0); --Holds the propagate signals from CLAs
signal gen_in : std_logic_vector(15 downto 0); --Holds the generate signals from CLAs
signal carry_in : std_logic_vector(15 downto 0); --Holds the carry signal from carry_logic
signal temp_result : std_logic_vector(15 downto 0); --Holds the temporary result to be driven out
--Component declarations
component cla_4bit
port (
a, b : in std_logic_vector(3 downto 0);
gen, prop : out std_logic_vector(3 downto 0)
);
end component;
component carry_logic
port (
g, p : in std_logic_vector(15 downto 0);
c_in : in std_logic;
carry : out std_logic_vector(15 downto 0);
c_out : out std_logic
);
end component;
--Actual behavior of module
begin
--b_in <= (b) when add_sub = '0' else (b_2scomp);
process (clk, reset)
begin
if reset = '0' then --At reset, everything is 0
a_in <= (others => '0');
b_in <= (others => '0');
b_2scomp <= (others => '0');
temp_result <= (others => '0');
elsif (rising_edge(clk)) then --Read in data to components on rising edge
if enable = '1' then --Only if enable is on
a_in <= a;
b_2scomp <= ((not b) + '1');
b_in <= (b) when add_sub = '0' else (b_2scomp);
end if;
elsif (falling_edge(clk)) then --Drive out values on falling edge
for i in 0 to 15 loop
temp_result(i) <= a_in(i) xor b_in(i) xor carry_in(i);
end loop;
result <= temp_result;
end if;
end process;
--portmapping of the components here. I don't think it'd be necessary to include them, but let me know if they are needed.
The ternary operator .. when .. else .. is not allowed inside a process block prior to VHDL-2008.
Solution 1: Write an ordinary if .. then .. else .. end if statement
Solution 2: Enable VHDL-2008 support in your tool chain
Solution 3: Write a function, lets say ite (if-then-else), which performs the ternary operation.