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
Related
i have created the structural and the behavioral code for a 1-bit ALU,as well as a control circuit .The control circuit decides the operation that will be conducted between two variables : a,b .
Here is my behavioral part of the code :
library ieee;
use ieee.std_logic_1164.all;
package erotima2 is
-- AND2 declaration
component myAND2
port (outnotA,outnotB: in std_logic; outAND: out std_logic);
end component;
-- OR2 declaration
component myOR2
port (outnotA,outnotB: in std_logic; outOR: out std_logic);
end component;
-- XOR2 declaration
component myXOR2
port (outnotA,outnotB: in std_logic; outXOR: out std_logic);
end component;
--fulladder declaration
component fulladder
port(CarryIn,outnotA,outnotB: in std_logic; sum,CarryOut: out std_logic);
end component;
--Ainvert declaration
component notA
port(a: in std_logic; signala: std_logic_vector(0 downto 0); outnotA: out std_logic);
end component;
--Binvert declaration
component notB
port(b: in std_logic; signalb: std_logic_vector(0 downto 0); outnotB: out std_logic);
end component;
--ControlCircuit declaration--
component ControlCircuit
port (
opcode : in std_logic_vector (2 downto 0);
signala,signalb : out std_logic_vector(0 downto 0);
operation : out std_logic_vector (1 downto 0);
CarryIn: out std_logic);
end component;
--mux4to1 declaration
component mux4to1
port(outAND, outOR, sum, outXOR: in std_logic; operation: in std_logic_vector(1 downto 0); Result: out std_logic);
end component;
end package erotima2;
--2 input AND gate
library ieee;
use ieee.std_logic_1164.all;
entity myAND2 is
port (outnotA,outnotB: in std_logic; outAND: out std_logic);
end myAND2;
architecture model_conc of myAND2 is
begin
outAND<= outnotA and outnotB;
end model_conc;
-- 2 input OR gate
library ieee;
use ieee.std_logic_1164.all;
entity myOR2 is
port (outnotA,outnotB: in std_logic; outOR: out std_logic);
end myOR2;
architecture model_conc2 of myOR2 is
begin
outOR <= outnotA or outnotB;
end model_conc2;
--2 input XOR gate
library ieee;
use ieee.std_logic_1164.all;
entity myXOR2 is
port(outnotA,outnotB: in std_logic; outXOR: out std_logic);
end myXOR2;
architecture model_conc3 of myXOR2 is
begin
outXOR <= outnotA xor outnotB;
end model_conc3;
--3 input full adder
library ieee;
use ieee.std_logic_1164.all;
entity fulladder is
port(CarryIn,outnotA,outnotB: in std_logic; sum,CarryOut: out std_logic);
end fulladder;
architecture model_conc4 of fulladder is
begin
CarryOut <= (outnotB and CarryIn) or (outnotA and CarryIn) or (outnotA and outnotB);
sum <= (outnotA and not outnotB and not CarryIn) or (not outnotA and outnotB and not CarryIn) or (not outnotA and not outnotB and CarryIn) or (outnotA and outnotB and CarryIn);
end model_conc4;
--1 input notA
library ieee;
use ieee.std_logic_1164.all;
entity notA is
port(a: in std_logic; signala:std_logic_vector(0 downto 0); outnotA: out std_logic);
end notA;
architecture model_conc6 of notA is
begin
with signala select
outnotA <= a when "0",
not a when others;
end model_conc6;
--1 input notB
library ieee;
use ieee.std_logic_1164.all;
entity notB is
port(b: in std_logic; signalb: std_logic_vector(0 downto 0); outnotB: out std_logic);
end notB;
architecture model_conc5 of notB is
begin
with signalb select
outnotB <= b when "0",
not b when others;
end model_conc5;
--4 input MUX
library ieee;
use ieee.std_logic_1164.all;
entity mux4to1 is
port(outAND, outOR, sum, outXOR: in std_logic; operation: in std_logic_vector(1 downto 0); Result: out std_logic);
end mux4to1;
architecture model_conc7 of mux4to1 is
begin
with operation select
Result<= outAND when "00",
outOR when "01",
sum when "10",
outXOR when OTHERS;
end model_conc7 ;
The behavioral part defines the logic gates of AND,OR,XOR, a full adder for numerical addition and substraction. It also contains a 4-to-1 multiplexer that chooses (depending on the value of the "operation" variable) which operation the alu will do. Lastly there is a function that inverts the variables in order to be more efficient with our logic gate usage( using the DeMorgan theorem so we don't have to create a NOR gate). The control unit initializes the variable inputs, as well as the carryIn variable of the full adder, depending on the variable "opcode". A board with every possible combination
Next is the Control Circuit part of the code, which implements the previous board.
`
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ControlCircuit is
port (
opcode :in std_logic_vector (2 downto 0);
signala, signalb : out std_logic_vector(0 downto 0);
operation : out std_logic_vector(1 downto 0);
CarryIn : out std_logic);
end ControlCircuit;
architecture model_conc9 of ControlCircuit is
--signal outAND,outOR,outXOR,sum,outnotA,outnotB : std_logic;
--signal operation : out std_logic_vector(1 downto 0);
begin
process(opcode)
begin
case opcode is
--AND--
when "000"=>
operation <= "00";
signala <= "0";
signalb <= "0";
CarryIn <= '0';
--OR--
when "001" =>
operation <= "01";
signala <= "0";
signalb <= "0";
CarryIn <= '0';
--ADD--
when "011" =>
operation <= "10";
signala <= "0";
signalb <= "0";
CarryIn <= '0';
--SUB--
when "010" =>
operation <= "10";
signala <= "0";
signalb <="1";
CarryIn <= '1';
--NOR--
when "101"=>
operation <= "00";
signala <= "1";
signalb <= "1";
CarryIn <= '0';
--xor
when "100" =>
operation <= "11";
signala <= "0";
signalb <= "0";
CarryIn <= '0';
--Adiafores times--
when others =>
operation <= "00";
signala <= "0";
signalb <= "0";
CarryIn <= '0';
end case;
end process;
end model_conc9;
`
Lastly here is the code that uses all the previous parts and and an RTL diagram that shows the code's result
library IEEE;
use ieee.std_logic_1164.all;
use work.erotima2.all;
entity structural is
port (a,b: in std_logic;
opcode : in std_logic_vector ( 2 downto 0);
Result,CarryOut : out std_logic);
end structural;
architecture alu of structural is
signal outAND,outOR,outXOR,sum,outnotA,outnotB,CarryIn : std_logic;
signal signala,signalb : std_logic_vector (0 downto 0);
signal operation : std_logic_vector (1 downto 0);
begin
u0 : myAND2 port map (outnotA,outnotB,outAND);
u1 : myOR2 port map (outnotA,outnotB,outOR);
u2 : myXOR2 port map (outnotA,outnotB,outXOR);
u3 : fulladder port map (CarryIn,outnotA,outnotB,sum,CarryOut);
u4 : notA port map (a,signala,outnotA);
u5 : notB port map (b,signalb,outnotB);
u6 : mux4to1 port map (outAND, outOR,sum, outXOR, operation, Result );
u8 : ControlCircuit port map(opcode,signala,signalb,operation,CarryIn);
end alu;
Now for the tough part, i need to use the 1-bit ALU 16 times as a component, to create a 16-bit ALU. It is important to keep the control circuit independent from the rest of the code. I have tried using an std_logic_vector ( 15 downto 0) but it did not work and i would like to use the previous code segments as a component. Can anyone give any tips or ideas that will help connect 16 1-bit ALUs to a complete 16-bit ALU? Thanks in advance for those who read this massive wall of text.
Your recent comment
Yes i understand that my code is weird but we were intsructed to invert the inputs according to this diagram . As for the duplicate post, i checked before posting and they were implemented only structurally, while in my case i need to write the behavioral part too.
Explains the issue, misspellings aside. You'll notice your architecture structural of entity structural doesn't match the signals shown on the above 1 bit alu diagram which doesn't contain an instantiated ControlCircuit.
If you were to provide a design unit that matched the above diagram you can hook up the 1 bit alu carry chain while deriving the carryin for the lsb from the control block which provides a + 1 and inversion for subtraction:
library ieee;
use ieee.std_logic_1164.all;
entity alu_16_bit is
port (
a: in std_logic_vector (15 downto 0);
b: in std_logic_vector (15 downto 0);
opcode: in std_logic_vector (2 downto 0);
result: out std_logic_vector (15 downto 0);
carryout: out std_logic
);
end entity;
architecture foo of alu_16_bit is
component alu_1_bit is
port (
a: in std_logic;
b: in std_logic;
ainvert: in std_logic;
binvert: in std_logic;
carryin: in std_logic;
operation: in std_logic_vector (1 downto 0);
result: out std_logic;
carryout: out std_logic
);
end component;
component controlcircuit is
port (
opcode: in std_logic_vector(2 downto 0);
ainvert: out std_logic;
binvert: out std_logic;
operation: out std_logic_vector(1 downto 0);
carryin: out std_logic -- invert a or b, add + 1 for subtract
);
end component;
signal ainvert: std_logic;
signal binvert: std_logic;
signal operation: std_logic_vector (1 downto 0);
signal carry: std_logic_vector (16 downto 0);
begin
CONTROL_CIRCUIT:
controlcircuit
port map (
opcode => opcode,
ainvert => ainvert,
binvert => binvert,
operation => operation,
carryin => carry(0) -- for + 1 durring subtract
);
GEN_ALU:
for i in 0 to 15 generate
ALU:
alu_1_bit
port map (
a => a(i),
b => b(i),
ainvert => ainvert,
binvert => binvert,
carryin => carry(i),
operation => operation,
result => result(i),
carryout => carry(i + 1)
);
end generate;
carryout <= carry(16) when operation = "10" else '0';
end architecture;
This represents moving ControlCircuit out of structural - only one copy is needed, renaming structural alu_1_bit and making the ports match.
There's a new top level alu_16_bit containing a single instance of ControlCircuit along with sixteen instances of alu_1_bit elaborated from the generate statement using the generate parameter i to index into arrays values for connections.
This design has been behaviorally implemented independently using the Opcode table you provided the link to:
as well as an independent fulladder used in alu_1_bit and appears functional.
This implies your design units haven't been validated.
I'm currently learning about writing testbenchs for my VHDL components. I am trying to test a clock synchronizer, just made up of two cascaded D-type flip flops. I have written a testbench, supplying a clock and appropriate input signal stimuli but I see no output changing when I simulate, it just remains at "00".
I would be very grateful for any assistance!
EDIT: the dff component is a standard Quartus component, not quite sure how to get at the internal code.
Here is the component VHDL:
library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
--This device is to synchronize external signals that are asynchronous to the
--system by use of two cascaded D-Type flip flops, in order to avoid metastability issues.
--Set the generic term Nbits as required for the number of asynchronous inputs to
--be synchronized to the system clock OUTPUT(0) corresponds to INPUT(0), ect.
entity CLOCK_SYNCHRONIZER is
generic(Nbits : positive := 2);
port
(
--Define inputs
SYS_CLOCK : in std_logic;
RESET : in std_logic;
INPUT : in std_logic_vector(Nbits-1 downto 0);
--Define output
OUTPUT : out std_logic_vector(Nbits-1 downto 0) := (others=>'0')
);
end entity;
architecture v1 of CLOCK_SYNCHRONIZER is
--Declare signal for structural VHDL component wiring
signal A : std_logic_vector(Nbits-1 downto 0);
--Declare D-Type Flip-Flop
component dff
port(D : in std_logic; CLK : in std_logic; CLRN : in std_logic; Q : out std_logic);
end component;
begin
--Generate and wire number of synchronizers required
g1 : for n in Nbits-1 downto 0 generate
c1 : dff port map(D=>input(n), CLK=>sys_clock, Q=>A(n), CLRN=>reset);
c2 : dff port map(D=>A(n), CLK=>sys_clock, Q=>output(n), CLRN=>reset);
end generate;
end architecture v1;
And here is the testbench:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity testbench is
end entity;
architecture v1 of testbench is
component CLOCK_SYNCHRONIZER
generic(Nbits : positive := 2);
port
(
--Define inputs
SYS_CLOCK : in std_logic;
RESET : in std_logic;
INPUT : in std_logic_vector(Nbits-1 downto 0);
--Define output
OUTPUT : out std_logic_vector(Nbits-1 downto 0)
);
end component;
constant Bus_width : integer := 2;
signal SYS_CLOCK : std_logic := '0';
signal RESET : std_logic := '1';
signal INPUT : std_logic_vector(Bus_width-1 downto 0) := (others=>'0');
signal OUTPUT : std_logic_vector(Bus_width-1 downto 0) := (others=>'0');
begin
C1 : CLOCK_SYNCHRONIZER
generic map(Nbits=>Bus_width)
port map(SYS_CLOCK=>SYS_CLOCK, RESET=>RESET, INPUT=>INPUT, OUTPUT=>OUTPUT);
always : process
begin
for i in 0 to 50 loop
INPUT <= "11";
wait for 24ns;
INPUT <= "00";
wait for 24ns;
end loop;
WAIT;
end process;
clk : process
begin
for i in 0 to 50 loop
SYS_CLOCK <= '1';
wait for 5ns;
SYS_CLOCK <= '0';
wait for 5ns;
end loop;
WAIT;
end process;
end architecture v1;
The problem is that you have not compiled an entity to bind to the dff component. See this example on EDA Playground, where you see the following warnings:
ELAB1 WARNING ELAB1_0026: "There is no default binding for component
"dff". (No entity named "dff" was found)." "design.vhd" 45 0 ...
ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__1/c1 : dff not bound.
ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__1/c2 : dff not bound.
ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__0/c1 : dff not bound.
ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__0/c2 : dff not bound.
Given you have no configuration, this needs to have be called dff and must have exactly the same ports as the dff component, ie:
entity dff is
port(D : in std_logic; CLK : in std_logic; CLRN : in std_logic; Q : out std_logic);
end entity;
(Google "VHDL default binding rules")
This needs to model the functionality of the dff flip-flop. I have assumed the following functionality:
architecture v1 of dff is
begin
process (CLK, CLRN)
begin
if CLRN = '0' then
Q <= '0';
elsif rising_edge(CLK) then
Q <= D;
end if;
end process;
end architecture v1;
You can see this now does something more sensible on EDA Playground. (I haven't checked to see whether it is doing the right thing.)
BTW: why are you initialising this output? That seems a strange thing to do:
OUTPUT : out std_logic_vector(Nbits-1 downto 0) := (others=>'0')
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;
I have a School Lab that I must do pertaining to creating a sequential multiplier in VHDL. My issues is happening before making the finite state machine for the sequential multiplier. I can not get the base model to multiply correctly, I think I have a issue in my test bench but am not 100% sure of this. I still have doubt that the issue is in my code.
Top Design (basically calling the D-Flip-Flops, MUX and Adder)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use ieee.std_logic_arith.all;
--use ieee.std_logic_unsigned.all;
entity toplvds is
port( A,B: in std_logic_vector(3 downto 0);
Zero: in std_logic_vector(3 downto 0);
clk, clr, load, loadP, sb: in std_logic;
Po: out std_logic_vector(7 downto 0));
end toplvds;
architecture Behavioral of toplvds is
component dffa
port( dina: in std_logic_vector(3 downto 0);
clr, clk, load: in std_logic;
q: out std_logic_vector(3 downto 0));
end component;
component dffb
port( dinb: in std_logic_vector(3 downto 0);
clr, clk, load, sb: in std_logic;
qb0: out std_logic);
end component;
component mux
port( d0,d1: in std_logic_vector(3 downto 0);
s: in std_logic;
y: out std_logic_vector(3 downto 0));
end component;
component adder
port( a,b: in std_logic_vector(3 downto 0);
cry: out std_logic;
r: out std_logic_vector(3 downto 0));
end component;
component dffP
port( dinp: in std_logic_vector(3 downto 0);
carry: in std_logic;
clr, clk, loadP, sb: in std_logic;
PHout: out std_logic_vector (3 downto 0);
P: out std_logic_vector(7 downto 0));
end component;
signal Wire1: std_logic_vector(3 downto 0);
signal Wire2: std_logic_vector(3 downto 0);
signal Wire3: std_logic;
signal Wire4: std_logic_vector(3 downto 0);
signal Wire5: std_logic_vector(3 downto 0);
signal Wire6: std_logic_vector(3 downto 0);
signal Wire7: std_logic;
begin
Wire1 <= Zero;
u1: dffa port map (dina=>A,clr=>clr,clk=>clk,load=>load,q=>Wire2);
u2: dffb port map (dinb=>B,clr=>clr,clk=>clk,load=>load,sb=>sb,qb0=>Wire3);
u3: mux port map (d0=>Wire2,d1=>Wire1,s=>Wire3,y=>Wire4);
u4: adder port map (a=>Wire6,b=>Wire4,cry=>Wire7,r=>Wire5);
u5: dffp port map (dinp=>Wire5,carry=>Wire7,clr=>clr,clk=>clk,loadP=>loadP,sb=>sb,PHout=>Wire6,P=>Po);
end Behavioral;
D-Flip-Flop for Multiplicand
library ieee;
use ieee.std_logic_1164.all;
entity dffa is
port( dina: in std_logic_vector(3 downto 0);
clr, clk, load: in std_logic;
q: out std_logic_vector(3 downto 0));
end dffa;
architecture beh of dffa is
begin
process(clk,clr)
begin
if(clr = '1') then
q <= ( others => '0');
elsif (rising_edge(clk)) then
if(load = '1') then
q <= dina;
end if;
end if;
end process;
end beh;
D-Flip-Flop for Multiplier
library ieee;
use ieee.std_logic_1164.all;
entity dffb is
port( dinb: in std_logic_vector(3 downto 0);
clr, clk, load, sb: in std_logic;
qb0: out std_logic);
end dffb;
architecture beh of dffb is
signal q: std_logic_vector(3 downto 0);
begin
qb0 <= q(0);
process(clk,clr, load, sb)
begin
if(clr = '1') then
q <= ( others => '0');
elsif (rising_edge(clk)) then
if(load = '1') then
q <= dinb;
elsif (sb = '1') then
q <= '0' & q ( 3 downto 1);
end if;
end if;
end process;
end beh;
MUX
library ieee;
use ieee.std_logic_1164.all;
entity mux is
port( d0,d1: in std_logic_vector(3 downto 0);
s: in std_logic;
y: out std_logic_vector(3 downto 0));
end mux;
architecture beh of mux is
begin
y <= d0 when s = '1' else d1;
end beh;
Adder
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity adder is
port( a,b: in std_logic_vector(3 downto 0);
cry: out std_logic;
r: out std_logic_vector(3 downto 0));
end adder;
architecture beh of adder is
signal temp : std_logic_vector(4 downto 0);
begin
temp <= ('0' & a) + ('0' & b);
r <= temp(3 downto 0);
cry <= temp(4);
end beh;
D-Flip-Flop for Product
library ieee;
use ieee.std_logic_1164.all;
entity dffp is
port( dinp: in std_logic_vector(3 downto 0);
carry: in std_logic;
clr, clk, loadP, sb: in std_logic;
PHout: out std_logic_vector (3 downto 0);
P: out std_logic_vector(7 downto 0));
end dffp;
architecture beh of dffp is
signal q: std_logic_vector(7 downto 0);
begin
--qp0 <= q(0);
process(clk,clr, loadP, sb)
begin
if(clr = '1') then
q <= ( others => '0');
elsif (rising_edge(clk)) then
if(loadP = '1') then
--q <= "00000000";
q(7 downto 4) <= dinp;
elsif (sb = '1') then
q <= carry & q ( 7 downto 1);
--else
--q(7 downto 4) <= dinp;
end if;
end if;
end process;
PHout <= q(7 downto 4);
P <= q;
end beh;
TEST-BENCH Code
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY toplvds_tb IS
END toplvds_tb;
ARCHITECTURE behavior OF toplvds_tb IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT toplvds
PORT(
A : IN std_logic_vector(3 downto 0);
B : IN std_logic_vector(3 downto 0);
Zero : IN std_logic_vector(3 downto 0);
clk : IN std_logic;
clr : IN std_logic;
load : IN std_logic;
loadP : IN std_logic;
sb : IN std_logic;
Po : OUT std_logic_vector(7 downto 0)
);
END COMPONENT;
--Inputs
signal A : std_logic_vector(3 downto 0) := (others => '0');
signal B : std_logic_vector(3 downto 0) := (others => '0');
signal Zero : std_logic_vector(3 downto 0) := (others => '0');
signal clk : std_logic := '0';
signal clr : std_logic := '0';
signal load : std_logic := '0';
signal loadP : std_logic := '0';
signal sb : std_logic := '0';
--Outputs
signal Po : std_logic_vector(7 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: toplvds PORT MAP (
A => A,
B => B,
Zero => Zero,
clk => clk,
clr => clr,
load => load,
loadP => loadP,
sb => sb,
Po => Po
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
A <= "1011";
B <= "1101";
Zero <="0000";
load <= '0';
sb <= '0';
clr <= '1';
wait for 12 ns;
clr <= '0'; load <= '1';
wait for 12 ns;
load <= '0'; sb <= '1';
wait for 12 ns;
sb <= '0'; loadP <= '1';
wait for 12 ns;
loadP <= '0'; sb <= '1';
wait for 12 ns;
sb <= '0'; loadP <= '1';
wait for 12 ns;
loadP <= '0'; sb <= '1';
wait for 12 ns;
sb <= '0'; loadP <= '1';
wait for 12 ns;
loadP <= '0'; sb <= '1';
wait for 12 ns;
sb <= '0'; loadP <= '1';
wait for 12 ns;
loadP <= '0'; sb <= '1';
wait for 20 ns;
loadP <= '0'; sb <= '0';
wait;
end process;
END;
Sorry that I have not commented the code for better understanding. I know this will be hard to follow but I hope someone will. I will also attach an image of the figure of the sequential multiplier I am following, the circuit design.
4 by 4 binary sequential multiplier circuit
4 by 4 binary sequential multiplier circuit - more
Well it was indeed something in the testbench that was giving issues. I worked it out in the lab with fellow classmates. Thank You for your help anyways it is much appreciated.
p.s. All I did was changed some timing values in the testbench at the very bottom to when the load and shift bit would happen and I got it to work.
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)