I'm having a bit of trouble creating a prng using the lfsr method. Here is my code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity pseudorng is
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
constant seed: STD_LOGIC_VECTOR(7 downto 0) := "00000001";
end pseudorng;
architecture Behavioral of pseudorng is
signal temp: STD_LOGIC;
signal Qt: STD_LOGIC_VECTOR(7 downto 0);
begin
PROCESS(clock)
BEGIN
IF rising_edge(clock) THEN
IF (reset='1') THEN Qt <= "00000000";
ELSE Qt <= seed;
END IF;
temp <= Qt(4) XOR Qt(3) XOR Qt(2) XOR Qt(0);
--Qt <= temp & Qt(7 downto 1);
END IF;
END PROCESS;
check <= temp;
Q <= Qt;
end Behavioral;
Here is the simulation I have ran:
prng sim
Firstly, the check output is just there so I can monitor the output of the temp signal. Secondly, the line that is commented out is what is causing the problem.
As can be seen from the simulation, on the first rising edge of the clock, the Qt signal reads the seed. However, and this is my question, for some reason the temp signal only XORs the bits of the Qt signal on the second rising edge of the clock. It remains undefined on the first clock pulse. Why is that? If it operated on the first rising edge right after the Qt signal reads the seed, then I could uncomment the line that shifts the bits and it would solve my problem. Any help would be much appreciated!
Here is the test bench if anyone cares:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_pseudorng is
end tb_pseudorng;
architecture bench of tb_pseudorng is
COMPONENT pseudorng
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
END COMPONENT;
signal clock1: STD_LOGIC;
signal reset1: STD_LOGIC;
signal Q1: STD_LOGIC_VECTOR(7 downto 0);
signal check1: STD_LOGIC;
begin
mapping: pseudorng PORT MAP(
clock => clock1,
reset => reset1,
Q => Q1,
check => check1);
clock: PROCESS
BEGIN
clock1<='0'; wait for 50ns;
clock1<='1'; wait for 50ns;
END PROCESS;
reset: PROCESS
BEGIN
reset1<='0'; wait for 900ns;
END PROCESS;
end bench;
I made some slight modifications to what you had (you are pretty much there though); I don't think the LFSR would step properly otherwise. I added an enable signal to the LFSR so you can effectively control when you want it to step. Resulting sim is here.
Just as a sidenote, you could also include a load and seed inputs if you wanted to seed the LFSR with a different value (instead of making it const).
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity pseudorng is
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
en : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
-- constant seed: STD_LOGIC_VECTOR(7 downto 0) := "00000001";
end pseudorng;
architecture Behavioral of pseudorng is
--signal temp: STD_LOGIC;
signal Qt: STD_LOGIC_VECTOR(7 downto 0) := x"01";
begin
PROCESS(clock)
variable tmp : STD_LOGIC := '0';
BEGIN
IF rising_edge(clock) THEN
IF (reset='1') THEN
-- credit to QuantumRipple for pointing out that this should not
-- be reset to all 0's, as you will enter an invalid state
Qt <= x"01";
--ELSE Qt <= seed;
ELSIF en = '1' THEN
tmp := Qt(4) XOR Qt(3) XOR Qt(2) XOR Qt(0);
Qt <= tmp & Qt(7 downto 1);
END IF;
END IF;
END PROCESS;
-- check <= temp;
check <= Qt(7);
Q <= Qt;
end Behavioral;
And tb:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_pseudorng is
end tb_pseudorng;
architecture bench of tb_pseudorng is
COMPONENT pseudorng
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
en : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
END COMPONENT;
signal clock1: STD_LOGIC;
signal reset1: STD_LOGIC;
signal Q1: STD_LOGIC_VECTOR(7 downto 0);
signal check1: STD_LOGIC;
signal en : STD_LOGIC;
begin
mapping: pseudorng PORT MAP(
clock => clock1,
reset => reset1,
en => en,
Q => Q1,
check => check1);
clock: PROCESS
BEGIN
clock1 <= '0'; wait for 50 ns;
clock1 <= '1'; wait for 50 ns;
END PROCESS;
reset: PROCESS
BEGIN
reset1 <= '0';
en <= '1';
wait for 900 ns;
END PROCESS;
end bench;
Related
I've been asked at the university to make a 4-bit bidirectional shift register. I did it first this way:
-- bidirektionale shift register mit data-load und serielle(R/L) output
library ieee;
use ieee.std_logic_1164.all;
entity bi_shift_reg is
port( din: in std_logic_vector(3 downto 0);
set, n_reset: in std_logic;
sR, sL: in std_logic; -- Shift-Right/Shift-Left
data_load: in std_logic;
clk: in std_logic;
dout: inout std_logic_vector(3 downto 0);
s_dout_R: out std_logic; -- Serial Shift-Right output
s_dout_L: out std_logic -- Serial Shift-Left output
);
end bi_shift_reg;
architecture arch of bi_shift_reg is
begin
process(clk,set,n_reset)
begin
-- reset (low aktiv)
if n_reset = '0' then dout <= "0000";
-- set
elsif set = '1' then dout <= "1111";
-- data-load
elsif(rising_edge(clk) and data_load = '1') then
s_dout_R <= din(0);
s_dout_L <= din(3);
dout <= din;
-- shift right
elsif(rising_edge(clk) and sR = '1') then
s_dout_R <= din(0);
dout(2 downto 0) <= dout(3 downto 1);
-- shift left
elsif(rising_edge(clk) and sL = '1') then
s_dout_L <= din(3);
dout(3 downto 1) <= dout(2 downto 0);
end if;
end process;
end arch;
but then I heard that I needed to use my previous coded D-Flipflop as a component for the shift register. So my question is: since I have new inputs (data_load,shift_left and shift_right) and outputs(Serial Shift-Right, Serial Shift-Left) how can I add them in my code along with the d-ff component? is it possible to use a component and process together ?
This is my d-ff code with asynchronous activ-low reset and asynchronous set:
library ieee;
use ieee.std_logic_1164.all;
entity d_flipflop is
port( d, clk, set, n_reset: in std_logic;
q, qn: out std_logic
);
end d_flipflop;
architecture arch of d_flipflop is
begin
process(clk,set,n_reset)
variable temp: std_logic; -- zwischenergebniss
begin
if n_reset = '0' then
temp := '0';
elsif set = '1' then
temp := '1';
elsif rising_edge(clk) then
temp := d;
end if;
q <= temp;
qn <= not temp;
end process;
end arch;
How can I use my flipflop to achieve the same result as the code for the shift-register ?
Thank you in advance for your answers :D
After several good questions in the comment track by the OP, it is reasonable to post some design that can serve as an example for a solution.
Please note, that there was not any precise specification of the intended operation, e.g. what is priority between different inputs, and how should timing be for outputs, so the code below is provided with the intention of showing some VHDL structures that may works as a template for further update by the OP.
--###############################################################################
-- d_flipflop
library ieee;
use ieee.std_logic_1164.all;
entity d_flipflop is
port(d, clk, set, n_reset : in std_logic;
q, qn : out std_logic
);
end d_flipflop;
architecture arch of d_flipflop is
begin
process(clk, set, n_reset)
variable temp : std_logic; -- zwischenergebniss
begin
if n_reset = '0' then
temp := '0';
elsif set = '1' then
temp := '1';
elsif rising_edge(clk) then
temp := d;
end if;
q <= temp;
qn <= not temp;
end process;
end arch;
--###############################################################################
-- bi_shiftReg_ff
library ieee;
use ieee.std_logic_1164.all;
entity bi_shiftReg_ff is
port(din : in std_logic_vector(3 downto 0);
set, n_reset : in std_logic;
sR, sL : in std_logic; -- Shift-Right/Shift-Left
data_load : in std_logic;
clk : in std_logic;
dout : out std_logic_vector(3 downto 0);
s_dout_R : out std_logic; -- Shift-Right output
s_dout_L : out std_logic -- Shift-Left output
);
end bi_shiftReg_ff;
architecture arch of bi_shiftReg_ff is
-- FF component
component d_flipflop is
port(d, clk, set, n_reset : in std_logic;
q, qn : out std_logic
);
end component;
-- FF data input
signal d : std_logic_vector(3 downto 0);
-- FF data output
signal q : std_logic_vector(3 downto 0);
signal qn : std_logic_vector(3 downto 0); -- Unused, but included for completness
begin
-- Combinatorial process, thus making gates only
process (all)
begin
-- data-load
if (data_load = '1') then
d <= din;
-- shift right; priority over shift left
elsif (sR = '1') then
d <= '0' & q(q'left downto 1); -- Discard right-most bit in the right shift
-- shift left
elsif (sL = '1') then
d <= q(q'left - 1 downto 0) & '0'; -- Discard left-most bit in the left shift
end if;
end process;
-- State held in FFs
GEN_REG : for i in 0 to 3 generate
REGX : d_flipflop port map
(d(i), clk, set, n_reset, q(i), qn(i));
end generate;
-- Outputs drive
dout <= q;
s_dout_R <= q(q'right); -- Bit 0, but shown with VHDL attributes
s_dout_L <= q(q'left); -- Bit 3, --||--
end arch;
--###############################################################################
-- EOF
hi i' trying to do a 4 bit ripple carry adder with VHDL. The problem is that i'm trying to do a testbench to simulate it in ModelSim, but it doesn't work. This is the code and also the code reported by ModelSim:
Full adder code:
library ieee;
use ieee.std_logic_1164.all;
entity fullAdder is
port( -- Input of the full-adder
a : in std_logic;
-- Input of the full-adder
b : in std_logic;
-- Carry input
c_i : in std_logic;
-- Output of the full-adder
o : out std_logic;
-- Carry output
c_o : out std_logic
);
end fullAdder;
architecture data_flow of fullAdder is
begin
o <= a xor b xor c_i;
c_o <= (a and b) or (b and c_i) or (c_i and a);
end data_flow;
Ripple carry adder code:
library ieee;
use ieee.std_logic_1164.all;
entity Ripple_Carry_Adder is
Port (
A: in std_logic_vector (3 downto 0);
B:in std_logic_vector (3 downto 0);
Cin:in std_logic;
S:out std_logic_vector(3 downto 0);
Cout:out std_logic
);
end Ripple_Carry_Adder;
architecture data_flow2 of Ripple_Carry_Adder is
component fullAdder
Port(
A:in std_logic;
B:in std_logic;
Cin:in std_logic;
S:out std_logic;
Cout:out std_logic
);
end component;
signal c1,c2,c3:STD_LOGIC;
begin
FA1:fullAdder port map(A(0),B(0), Cin, S(0), c1);
FA2:fullAdder port map(A(1),B(1), c1, S(1), c2);
FA3:fullAdder port map(A(2),B(2), c2, S(2), c3);
FA4:fullAdder port map(A(3),B(3), c3, S(3), Cout);
end data_flow2;
code of Ripple carry adder testbench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
ENTITY ripple_carry_adder_tb is
end ripple_carry_adder_tb;
ARCHITECTURE behavior OF ripple_carry_adder_tb is
constant T_CLK : time := 10 ns; -- Clock period
constant T_RESET : time := 25 ns; -- Period before the reset deassertion
COMPONENT Ripple_Carry_Adder
PORT (
A:in std_logic_vector(3 downto 0);
B:in std_logic_vector(3 downto 0);
Cin:in std_logic;
S:out std_logic_vector(3 downto 0);
Cout:out std_logic
);
END COMPONENT;
signal A_tb:std_logic_vector(3 downto 0):="0000";
signal B_tb:std_logic_vector(3 downto 0):="0000";
signal Cin_tb:std_logic:='0';
signal S_tb:std_logic_vector(3 downto 0);
signal Cout_tb:std_logic;
signal clk_tb : std_logic := '0'; -- clock signal, intialized to '0'
signal rst_tb : std_logic := '0'; -- reset signal
signal end_sim : std_logic := '1';
BEGIN
clk_tb <= (not(clk_tb) and end_sim) after T_CLK / 2; -- The clock toggles after T_CLK / 2 when end_sim is high. When end_sim is forced low, the clock stops toggling and the simulation ends.
rst_tb <= '1' after T_RESET;
RP_1: Ripple_Carry_Adder PORT MAP(A=>A_tb,B=>B_tb,Cin=>Cin_tb,S=>S_tb,Cout=>Cout_tb);
d_process: process(clk_tb, rst_tb) -- process used to make the testbench signals change synchronously with the rising edge of the clock
variable t : integer := 0; -- variable used to count the clock cycle after the reset
begin
if(rst_tb = '0') then
A_tb <= "0000";
B_tb <= "0000";
Cin_tb<='0';
t := 0;
elsif(rising_edge(clk_tb)) then
A_tb<=A_tb+1;
B_tb<=B_tb+1;
t := t + 1;
if (t>32) then
end_sim <= '0';
end if;
end if;
end process;
END;
and this is errors reported by ModelSim when i trying to start simulation:
# ** Fatal: (vsim-3817) Port "c_i" of entity "fulladder" is not in the component being instantiated.
# Time: 0 ns Iteration: 0 Instance: /ripple_carry_adder_tb/RP_1/FA1 File:
C:/Users/utente/Desktop/full_adder.vhd Line: 11
# FATAL ERROR while loading design
# Error loading design
Why doesn't work? Thanks
I am implementing a multiplier in which i multiply A (8 bits) and B (8 bits), and store result at S. Number of bit required for output S is 16 bits. S have higher part SH and lower part SL.Every time i shift ,add operation is performed
i am getting following errors in my controller part :-
Attribute event requires a static signal prefix
is not declared.
"**" expects 2 arguments
and my code is:-
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity PIPO is
port (reset: in std_logic ;
B:IN STD_LOGIC_VECTOR (7 downto 0 );
LOAD:in std_logic ;
SHIFT:in std_logic ;
ADD:in std_logic ;
Sum:IN STD_LOGIC_VECTOR (7 downto 0 );
C_out:in std_logic ;
CLK:in std_logic ;
result: out STD_LOGIC_VECTOR (15 downto 0) ;
LSB:out std_logic ;
TB:out std_logic_vector (7 downto 0) );
end ;
architecture rtl OF PIPO is
signal temp1 : std_logic_vector(15 downto 0);
----temp2 -add
signal temp2 : std_logic ;
begin
process (CLK, reset)
begin
if reset='0' then
temp1<= (others =>'0');
temp2<= '0';
elsif (CLK'event and CLK='1') then
if LOAD ='1' then
temp1(7 downto 0) <= B;
temp1(15 downto 8) <= (others => '0');
end if ;
if ADD= '1' then
temp2 <='1';
end if;
if SHIFT= '1' then
if ADD= '1' then
------adder result ko add n shift
temp2<= '0';
temp1<=C_out & Sum & temp1( 7 downto 1 );
else
----only shift
temp1<= '0' & temp1( 15 downto 1 );
end if;
end if;
end if;
end process;
LSB <=temp1(0);
result<=temp1( 15 downto 0 );
TB <=temp1(15 downto 8);
end architecture rtl;
-------------------------------------------
-------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity Controller is
Port ( ADD :OUT STD_LOGIC;
SHIFT:OUT STD_LOGIC;
LOAD:OUT STD_LOGIC;
STOP:OUT STD_LOGIC;
STRT:IN STD_LOGIC;
LSB:IN STD_LOGIC;
CLK:IN STD_LOGIC;
reset:IN STD_LOGIC );
end ;
architecture rtl OF Contoller is
---RTL level code is inherently synchronous
signal count : unsigned (2 downto 0);
----differnt states
type state_typ is ( IDLE, INIT, TEST, ADDs, SHIFTs );
signal state : state_typ;
begin
--controller : process (ADD,SHIFT,LOAD,STOP,STRT,LSB,CLK,reset)
process (state)--(CLK, reset,ADD,SHIFT,LOAD,STOP,STRT,LSB)
begin
if reset='0' then
state <= IDLE;
count <= "000";
elsif (CLK'event and CLK='1') then
case state is
when IDLE =>
if STRT = '1' then
--- if STRT = '1' then
state <= INIT;
else
state <= IDLE;
end if;
when INIT =>
state <= TEST;
when TEST =>
if LSB = '0' then
state <= SHIFTs;
else
state <= ADDs;
end if;
when ADDs =>
state <= SHIFTs;
when SHIFTs =>
if count = "111" then
count <= "000";
state <= IDLE;
else
count<= std_logic_vector(unsigned(count) + 1);
state <= TEST;
end if;
end case;
end if;
end process ;
STOP <= '1' when state = IDLE else '0';
ADD <= '1' when state = ADDs else '0';
SHIFT <= '1' when state = SHIFTs else '0';
LOAD <= '1' when state = INIT else '0';
end architecture rtl;
----------------------------------------------
--------------------------------------------
---multiplicand
library ieee;
use ieee.std_logic_1164.all;
entity multiplicand is
port (A : in std_logic(7 downto 0);
reset :in std_logic;
LOAD : in std_logic;
TA : OUT STD_LOGIC(7 downto 0);
CLK : in std_logic );
end entity;
architecture rtl OF multiplicand is
begin
process (CLK, reset)
begin
if reset='0' then
TA <= (others =>'0'); -- initialize
elsif (CLK'event and CLK='1') then
if LOAD_cmd = '1' then
TA(7 downto 0) <= A_in; -- load B_in into register
end if;
end if ;
end process;
end architecture rtl;
------------------------------------------------------
------------------------------------------------------
---Full Adder
library ieee;
use ieee.std_logic_1164.all;
entity Full_Adder is
port (A : in std_logic;
B : in std_logic;
C_in : in std_logic;
Sum : out std_logic ;
C_out : out std_logic);
end;
architecture struc of Full_Adder is
begin
Sum <= A xor B xor C_in;
C_out <= (A and B) or (A and C_in) or (B and C_in);
end struc;
------------------------------------------------------------
-------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Adder is
Port ( TA : in STD_LOGIC_VECTOR (7 downto 0);
TB : in STD_LOGIC_VECTOR (7 downto 0);
Sum : out STD_LOGIC_VECTOR (7 downto 0);
C_in : in STD_LOGIC;
C_out : out STD_LOGIC);
end Adder;
architecture struc of Adder is
component Full_Adder is
port(A : in std_logic;
B : in std_logic;
C_in : in std_logic;
Sum : out std_logic ;
C_out : out std_logic);
end component;
signal C: std_logic_vector (7 downto 0);
begin
FA0:Full_Adder port map(TA(0), TB(0), C_in, Sum(0), C(0));
FA1: Full_Adder port map(TA(1), TB(1), C(0), Sum(1), C(1));
FA3: Full_Adder port map(TA(2),TB(2), C(1), Sum(2), C(2));
FA4: Full_Adder port map(TA(3), TB(3), C(2), Sum(3), C(3));
FA5: Full_Adder port map(TA(4), TB(4), C(3), Sum(4), C(4));
FA6: Full_Adder port map(TA(5), TB(5), C(4), Sum(5), C(5));
FA7: Full_Adder port map(TA(6), TB(6), C(5), Sum(6), C(6));
FA8: Full_Adder port map(TA(7), TB(7), C(6), Sum(7), C(7));
C_out <= C(7);
end struc;
------------------------------------------------------------
------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity multiplier is
Port ( num1 : in STD_LOGIC_VECTOR (7 downto 0);
num2 : in STD_LOGIC_VECTOR (7 downto 0);
result : out STD_LOGIC_VECTOR (15 downto 0);
CLK:in std_logic ;
reset:IN STD_LOGIC;
STRT:IN STD_LOGIC;
STOP:OUT STD_LOGIC );
end multiplier;
architecture rtl of Multiplier is
signal ADD :STD_LOGIC;
signal SHIFT :STD_LOGIC;
signal LOAD :STD_LOGIC;
signal LSB :STD_LOGIC;
signal A : STD_LOGIC_VECTOR (7 downto 0);
signal B :STD_LOGIC_VECTOR (7 downto 0);
signal Sum:STD_LOGIC_VECTOR (7 downto 0);
signal C_out:STD_LOGIC;
component Controller
port (
ADD :OUT STD_LOGIC;
SHIFT:OUT STD_LOGIC;
LOAD:OUT STD_LOGIC;
STOP:OUT STD_LOGIC;
STRT:IN STD_LOGIC;
LSB:IN STD_LOGIC;
CLK:IN STD_LOGIC;
reset:IN STD_LOGIC );
end component;
component Adder
port (
TA : in STD_LOGIC_VECTOR (7 downto 0);
TB : in STD_LOGIC_VECTOR (7 downto 0);
Sum : out STD_LOGIC_VECTOR (7 downto 0);
C_in : in STD_LOGIC;
C_out : out STD_LOGIC);
end component;
component PIPO
port (reset: in std_logic ;
B:IN STD_LOGIC_VECTOR (7 downto 0 );
LOAD:in std_logic ;
SHIFT:in std_logic ;
ADD:in std_logic ;
Sum:IN STD_LOGIC_VECTOR (7 downto 0 );
C_out:in std_logic ;
CLK:in std_logic ;
result: out STD_LOGIC_VECTOR (15 downto 0) ;
LSB:out std_logic ;
TB:out std_logic );
end component;
component multiplicand
port (A : in std_logic (7 downto 0);
reset :in std_logic;
LOAD : in std_logic;
TA : OUT STD_LOGIC(7 downto 0);
CLK : in std_logic );
end component ;
begin
inst_Controller: Controller
port map (ADD => ADD,
SHIFT =>SHIFT,
LOAD =>LOAD ,
STOP =>STOP,
STRT =>STRT,
LSB =>LSB ,
CLK =>CLK ,
reset =>reset
);
inst_multiplicand :multiplicand
port map (A =>A,
reset=>reset,
LOAD =>LOAD,
TA => TA(7 downto 0),
CLK => CLK
);
inst_PIPO :PIPO
port map ( reset => reset,
B => B ,
LOAD =>LOAD,
SHIFT=>SHIFT,
ADD=>ADD,
Sum=>Sum,
C_out=>C_out,
CLK=>CLK,
result=>result,
LSB=>LSB,
TB=>TB
);
inst_Full_Adder : Full_Adder
port map ( TA => TA,
TB =>TB,
Sum=>Sum ,
C_in=>C_in,
C_out=>C_out
);
end rtl;
Actually the space between CLK and the apostrophe/tick isn't significant
david_koontz#Macbook: token_test
elsif (CLK 'event and CLK ='1') then
KEYWD_ELSIF (151) elsif
DELIM_LEFT_PAREN ( 9) (
IDENTIFIER_TOKEN (128) CLK
DELIM_APOSTROPHE ( 8) '
IDENTIFIER_TOKEN (128) event
KEYWD_AND (134) and
IDENTIFIER_TOKEN (128) CLK
DELIM_EQUAL ( 25) =
CHAR_LIT_TOKEN ( 2) '1'
DELIM_RIGHT_PAREN ( 10) )
KEYWD_THEN (211) then
gives the same answer as:
david_koontz#Macbook: token_test
elsif (CLK'event and CLK ='1') then
KEYWD_ELSIF (151) elsif
DELIM_LEFT_PAREN ( 9) (
IDENTIFIER_TOKEN (128) CLK
DELIM_APOSTROPHE ( 8) '
IDENTIFIER_TOKEN (128) event
KEYWD_AND (134) and
IDENTIFIER_TOKEN (128) CLK
DELIM_EQUAL ( 25) =
CHAR_LIT_TOKEN ( 2) '1'
DELIM_RIGHT_PAREN ( 10) )
KEYWD_THEN (211) then
In vhdl, there is no lexical element parsing requiring a lack of white space. (Sorry Russel).
Correcting the other syntax ambiguities of your code (see below, missing context clause, Controller misspelled in the architecture declaration, count used as both a scalar and array subtype), results in two different VHDL analyzers swallowing the space between CLK and ' just fine.
The problem is in the tool you are using not actually being standard compliant or the code you present as having the problem isn't actually representational of the code generating the error. If a non-compliant tool it's likely a shortcoming you can live with, although there may be more things a bit more irksome.
david_koontz#Macbook: ghdl -a controller.vhdl
david_koontz#Macbook: nvc -a controller.vhdl
david_koontz#Macbook:
(no errors, it also elaborates without a test bench in ghdl, nvc disallows top level ports - which it is permitted to do by the standard)
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Controller is
Port (
ADD: OUT STD_LOGIC;
SHIFT: OUT STD_LOGIC;
LOAD: OUT STD_LOGIC;
STOP: OUT STD_LOGIC;
STRT: IN STD_LOGIC;
LSB: IN STD_LOGIC;
CLK: IN STD_LOGIC;
reset: IN STD_LOGIC
);
end entity;
architecture rtl OF Controller is
---RTL level code is inherently synchronous
signal count : std_logic_vector (2 downto 0);
----differnt states
type state_typ is ( IDLE, INIT, TEST, ADDs, SHIFTs );
signal state : state_typ;
begin
NOLABEL:
process (CLK, reset)
begin
if reset='0' then
state <= IDLE;
count <= "000";
elsif (CLK 'event and CLK ='1') then
case state is
when IDLE =>
if STRT = '1' then
state <= INIT;
else
state <= IDLE;
end if;
when INIT =>
state <= TEST;
when TEST =>
if LSB = '0' then
state <= SHIFTs;
else
state <= ADDs;
end if;
when ADDs =>
state <= SHIFTs;
when SHIFTs =>
if count = "111" then -- verify if finished
count <= "000"; -- re-initialize counter
state <= IDLE; -- ready for next multiply
else
count <= -- increment counter
std_logic_vector(unsigned(count) + 1);
state <= TEST;
end if;
end case;
end if;
end process;
---end generate; ???
STOP <= '1' when state = IDLE else '0';
ADD <= '1' when state = ADDs else '0';
SHIFT <= '1' when state = SHIFTs else '0';
LOAD <= '1' when state = INIT else '0';
end architecture rtl;
The error message appears to stem from the signal CLK (the prefix for the event attribtute). There is no other use of the event attribute in your code presented with the question. A signal is one of the elements of entity_class that can be decorated with an attribute.
In the VHDL LRM's section on predefined attributes 'EVENT can only decorate a signal, and CLK is a signal (declared in a port). In that section the prefix is required to be denoted by a static signal name.
Is CLK a static signal name? Yes it is. It's a scalar subtype declared in the entity declaration and is locally static (available at analysis time - it's a scalar, a simple name and not involving a generic).
And about now you might get why someone would wonder if the code in the question is representational of the code generating the error or the VHDL tool used is not compliant.
The error message you report is usually associated with trying to use 'EVENT with an indexed signal name, e.g. w(i)'event. (See Signal attributes on a signal vector).
You're going to kick yourself for this one:
elsif (CLK 'event and CLK ='1') then
Should be:
elsif (CLK'event and CLK ='1') then
See the difference?
Even better:
elsif rising_edge(CLK) then
It seems you're missing a clk entry in the process
Change the line reading:
process (state)--(CLK, reset,ADD,SHIFT,LOAD,STOP,STRT,LSB)
to read:
process (clk, reset)
I am designing a simple combination lock design in VHDL on a Spartan 6 FPGA. This error has come up and i am a bit confused to how i could fix it. I have "googled" this and according to this answer in this thread Too many comps of type “BUFGMUX” found to fit this deviceI beleive i know the problem but i am unsure how to solve it.
Now correct me if i am wrong but i believe this error came about due to the following code in my design
--clock divider
process(cclk,clr)
begin
if (clr ='1') then
Count200Hz <= X"00000";
--clk200 <= '0';
temp <= '0';
elsif rising_edge(cclk) then
if (Count200Hz = clk200HzEndVal) then
clk200 <= not temp;
Count200Hz <= X"00000";
else
Count200Hz <= Count200Hz + '1';
end if;
end if;
end process;
-- 2-bit counter
process(cclk,clr)
begin
if clr = '1' then
s <= "00";
elsif rising_edge(cclk) then
s <= s+1;
end if;
end process;
--state machine
state_mach:PROCESS(lclk, clr)
BEGIN
IF clr = '1' THEN
present_state <= idle;
ELSIF rising_edge(lclk) THEN
present_state <= next_state;
end if;
END PROCESS;
pulse_process: process(cclk, rst)
begin
if rst = '0' then
pulse <= '0';
count <= 0;
current_state <= idle;
elsif (rising_edge(cclk))then
current_state <= next_state;
....
These code are from different vhdl modules in my design.
does the ise believes that there are three different clock used in my design hence why the error is thrown??
The thing is that they are different clock but they stem from the systems clock ones the clock at an lower frequency, one is the clock pulse.
I have added my top-level design for some clarity
Any help is appreciated
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
entity simpleLock_top is
Port (
mclk : in STD_LOGIC;
rst : in STD_LOGIC;
btnl : in STD_LOGIC;
btnr : in STD_LOGIC;
sw : in STD_LOGIC_VECTOR (3 downto 0);
seg7 : out STD_LOGIC_VECTOR (6 downto 0);
an : out STD_LOGIC_VECTOR (3 downto 0);
led : out STD_LOGIC_VECTOR (7 DOWNTO 0);
dp : out STD_LOGIC);
end simpleLock_top;
architecture Behavioral of simpleLock_top is
component x7seg_msg is
Port (
x : in STD_LOGIC_VECTOR (15 downto 0);
cclk : in STD_LOGIC;
clr : in STD_LOGIC;
seg7 : out STD_LOGIC_VECTOR (6 downto 0);
an : out STD_LOGIC_VECTOR (3 downto 0);
dp : out STD_LOGIC);
end component;
component clkdiv is
Port (
cclk : in STD_LOGIC;
clr : in STD_LOGIC;
clk200 : out STD_LOGIC);
end component;
component simpleLock is
PORT (
lclk : IN STD_LOGIC;
clr : IN STD_LOGIC;
btnl : IN STD_LOGIC;
btnr : IN STD_LOGIC;
code : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
sw : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
led : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
digit : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
user_input : OUT STD_LOGIC_VECTOR(15 downto 0));
end component;
component clock_pulse is
PORT (
cclk : IN STD_LOGIC;
rst : IN STD_LOGIC;
trig : IN STD_LOGIC;
pulse : OUT STD_LOGIC);
end component;
constant code : STD_LOGIC_VECTOR(15 downto 0):= X"1234";
signal digit: STD_LOGIC_VECTOR(3 DOWNTO 0);
signal user_input : std_logic_vector(15 downto 0);
signal clk200, clkp, btn01: STD_LOGIC;
signal btn : STD_LOGIC_VECTOR(1 DOWNTO 0);
begin
btn(0) <= btnr;
btn(1) <= btnl;
btn01 <= btn(0) or btn(1);
--led <= X"00";
V1: clkdiv
port map(
cclk => mclk,
clr => rst,
clk200 => clk200);
V2: x7seg_msg
port map(
x => user_input,
cclk => clk200,
clr => rst,
seg7 => seg7,
an => an,
dp => dp );
V3: simpleLock
port map(
lclk => clkp,
clr => rst,
btnl => btnl,
btnr => btnr,
code => code,
sw => sw,
led => led,
digit => digit,
user_input => user_input);
V4: clock_pulse
port map(
cclk => clk200,
rst => rst,
trig => btn01,
pulse => clkp);
end Behavioral;
Clock Enable
In an FPGA design, it is often better to use the less possible different clocks.
If your "clock_pulse" module generate a one cycle clock pulse, don't use this pulse as a clock ('clkp' in your code), but as a clock enable ('enable' in the code below).
myproc : process(clk, rst)
begin
if rst = '1' THEN
-- your asynchronously reseted signals
elsif rising_edge(clk) THEN
if enable = '1' then
-- things that must be done when you get the one cycle pulse
end if;
end if;
end process;
But take care of any unmanaged clock domain crossing...
Hope this helps.
I have spent the whole day trying to solve the following problem. I am building a small averaging multichannel oscilloscope and I have the following module for storing the signal:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
entity storage is
port
(
clk_in : in std_logic;
reset : in std_logic;
element_in : in std_logic;
data_in : in std_logic_vector(11 downto 0);
addr : in std_logic_vector(9 downto 0);
add : in std_logic; -- add = '1' means add to RAM
-- add = '0' means write to RAM
dump : in std_logic;
element_out : out std_logic;
data_out : out std_logic_vector(31 downto 0)
);
end storage;
architecture rtl of storage is
component bram is
port
(
clk : in std_logic;
we : in std_logic;
en : in std_logic;
addr : in std_logic_vector(9 downto 0);
di : in std_logic_vector(31 downto 0);
do : out std_logic_vector(31 downto 0)
);
end component bram;
type state is (st_startwait, st_add, st_write);
signal current_state : state := st_startwait;
signal next_state : state := st_startwait;
signal start : std_logic;
signal we : std_logic;
signal en : std_logic;
signal di : std_logic_vector(31 downto 0);
signal do : std_logic_vector(31 downto 0);
signal data : std_logic_vector(11 downto 0);
begin
ram : bram port map
(
clk => clk_in,
we => we,
en => en,
addr => addr,
di => di,
do => do
);
process(clk_in, reset, start)
begin
if rising_edge(clk_in) then
if (reset = '1') then
current_state <= st_startwait;
else
start <= '0';
current_state <= next_state;
if (element_in = '1') then
start <= '1';
end if;
end if;
end if;
end process;
process(current_state, start, dump)
variable acc : std_logic_vector(31 downto 0);
begin
element_out <= '0';
en <= '1';
we <= '0';
case current_state is
when st_startwait =>
if (start = '1') then
acc(11 downto 0) := data_in;
acc(31 downto 12) := (others => '0');
next_state <= st_add;
else
next_state <= st_startwait;
end if;
when st_add =>
if (add = '1') then
acc := acc + do;
end if;
we <= '1';
di <= acc;
next_state <= st_write;
when st_write =>
if (dump = '1') then
data_out <= acc;
element_out <= '1';
end if;
next_state <= st_startwait;
end case;
end process;
end rtl;
Below is the BRAM module as copied from the XST manual. This is a no-change type of BRAM and I believe there is the problem. The symptom is that, while this simulates fine, I read only zeroes from the memory when I use the design on the device.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity bram is
port
(
clk : in std_logic;
we : in std_logic;
en : in std_logic;
addr : in std_logic_vector(9 downto 0);
di : in std_logic_vector(31 downto 0);
do : out std_logic_vector(31 downto 0)
);
end bram;
architecture rtl of bram is
type ram_type is array (0 to 999) of std_logic_vector (31 downto 0);
signal buf : ram_type;
begin
process(clk, en, we)
begin
if rising_edge(clk) then
if en = '1' then
if we = '1' then
buf(conv_integer(addr)) <= di;
else
do <= buf(conv_integer(addr));
end if;
end if;
end if;
end process;
end rtl;
What follows is a description of the chip use and the expected output. "clk_in" is a 50 MHz clock. "element_in" is '1' for 20 ns and '0' for 60 ns. "addr_in" iterates from 0 to 999 and changes every 80 ns. "element_in", "data_in", and "addr" are all aligned and synchronous. Now "add" is '1' for 1000 elements, then both "add" and "dump" are zero for 8000 elements and, finally "dump" is '1' for 1000 elements. Now, if I have a test bench that supplies "data_in" from 0 to 999, I expect data_out to be 0, 10, 20, 30, ..., 9990 when "dump" is '1'. That is according to the simulation. In reality I get 0, 1, 2, 3, ..., 999....
Some initial issues to address are listed below.
The process(current_state, start, dump) in storage entity looks like it is
intended to implement a combinatorial element (gates), but the signal (port)
data_in is not in the sensitivity list.
This is very likely to cause a difference between simulation and synthesis
behavior, since simulation will typically only react to the signals in the
sensitivity list, where synthesis will implement the combinatorial design and
react on all used signals, but may give a warning about incomplete sensitivity
list or inferred latches. If you are using VHDL-2008 then use can use a
sensitivity list of (all) to have the process sensitivity to all used
signals, and otherwise you need to add missing signals manually.
The case current_state is in process(current_state, start, dump) lacks an
when others => ..., so the synthesis tool has probably given you a warning
about inferred latches. This should be fixed by adding the when others =>
with and assign all signals driven by the process to the relevant value.
The use clause lists:
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
But both of these should not be used at the same time, since they declare some
of the same identifiers, for example is unsigned declared in both. Since the
RAM uses std_logic_unsigned I suggest that you stick with that only, and
delete use of numeric_std. For new code I would though recommend use of
numeric_std.
Also the process(clk_in, reset, start) in storage entity implements a
sequential element (flip flop) sensitive to only rising edge of clk_in, so
the two last signals in sensitivity list ..., reset, start) are unnecessary,
but does not cause a problem.