port map in structural VHDL code - vhdl

I have the following code for a structural modeling in VHDL. When I try to compile it (ghdl -a filename.vhdl), I get this error in the 4 lines commented below: "<=" or ":=" expected instead of port
BTW, I had already defined the components used before the code block below.
What's wrong with my code? Am I not allowed to use port map inside a process/if-statement?
What can I do to fix this? Thanks!
-- Entity Definition
entity jk is
port(
CP: in std_logic; -- clock signal
J : in std_logic; -- J signal
K : in std_logic; -- K signal
Q : inout std_logic; -- Q signal
QN : inout std_logic; -- Q' signal
reset : in std_logic -- reset signal
);
end entity jk;
architecture dev1 of jk is
-- declare the singals that outputs the results of some gates
signal a, b, internal_q, internal_qn : std_logic;
-- get each component needed
component and3 is
port(o0 : out std_logic; i0, i1, i2: in std_logic);
end component and3;
component nor2 is
port(o0 : out std_logic; i0, i1: in std_logic);
end component nor2;
begin
internal_q <= Q; -- used to show internal Q value
QN <= not Q; -- inverse of Q
internal_qn <= QN; -- used to show internal QN value
process is
begin
if (reset = '0') then -- asynchronous reset
Q <= '0';
internal_qn <= '0';
elsif rising_edge(CP) then -- on positive clock edge
-- AND gate outputs
g0: and3 port map(a, internal_q, K, CP); -- error
g1: and3 port map(b, internal_qn, J, CP); - error
-- NOR gate outputs
g2: nor2 port map(Q, a, internal_qn); -error
g3: nor2 port map(QN, b, internal_q); -error
end if;
end process;
end architecture dev2;

No, you are not allowed to instantiate components (use port maps) inside of a process.
You should be instantiating your components below the begin statement of your architecture. Wire them up there appropriately. Your process should drive all of the registered logic. I actually don't see any need for a process statement at all in this code. Since all of your inputs are coming from your entity (I assume) then you really don't need to do any registered logic in this file.
Can you post your entity as well? I cannot see where signals J and K and CP and Q and QN are being defined.

Related

4bit transfer using synchronous d flip-flop( transfer 4bit from register a to register b)

When I run this code two errors appear that say "Actual parameter type in port map does not match the type of the formal port 's'. I need help to understand how to fix these.
-- code that try in EDA playground to transfer from one register to another
-- library
library ieee;
use ieee. std_logic_1164.all;
-- declaration for d flip-flop
entity D_FF is
PORT( D : in std_logic_vector(7 downto 0);
s :in std_logic;
CLOCK: in std_logic;
Q: out std_logic_vector(7 downto 0));
end D_FF;
architecture behavioral of D_FF is
-- signals declaration
signal s1,s2,s3,s4,s5,s6,s7,s8: std_logic;
begin
--transfer the 4 bit to another register
s1 <= D(0) and (not s);
Q(0) <= s and D(0);
s2 <= D(1) and (not s);
Q(1) <= (Q(0)and s) or s2;
s3 <= D(2) and (not s);
Q(2) <= (Q(1)and s) or s3;
s4 <= D(3) and not s;
Q(3) <= (Q(2)and s)or s4;
s5 <= D(4) and not s;
Q(4) <= (Q(3)and s)or s5;
s6 <= D(5) and not s;
Q(5) <= (Q(4)and s)or s6;
s7 <= D(6) and not s;
Q(6) <= (Q(5)and s)or s7;
s8 <= D(7) and not s;
Q(7) <= (Q(6)and s)or s8;
end behavioral;
------------------------------
-- testbench
------------------------------
-- library
library ieee;
use ieee. std_logic_1164.all;
entity testbench is
-- empty entity
end testbench;
-----------------------------
architecture tb of testbench is -- testbench
-- architecture -- REDUNDANT transcription error?
-- component declaration
component D_FF is
PORT( D : in std_logic_vector(7 downto 0);
s :in std_logic;
CLOCK: in std_logic;
Q: out std_logic_vector(7 downto 0));
end component;
-- signals that need in testbench -- COMMENT DELIMITER transcription error?
signal D_s: std_logic_vector(7 downto 0);-- signals for entity i/o
signal Q_s: std_logic_vector(7 downto 0);-- signals for entity i/o
signal s_s: std_logic;
signal CLOCK_s: std_logic;
-- is the signal that must be run 4 time to transfer the bit
signal loop_count: integer;
begin
dut:D_FF port map(D_s,Q_s,s_s,CLOCK_s);
-- design under test instantiation
stimProcess: process --
--stimulus generator
begin
--the run 4 time this to transfer the 4 bit
for loop_counter in 0 to 3 loop
D_s <= "01100000";
wait until CLOCK_s = '1' and CLOCK_s'event;
end loop;
end process stimProcess;
-- without sensitivity list
end tb;
You are using a positional association for the port map. When you do this, the order of ports in your port map must match the order of ports in your component declaration. Using positional association, the proper order is:
dut:D_FF port map(D_s,s_s,CLOCK_s,Q_s);
Note that in your example, you've connected the signal Q_s to s, s_s to CLOCK, and CLOCK_s to Q (because your order was not the same).
I always prefer named association. On the left, you have your "formal" (the port outlined in your component declaration). On the right, you have the "actual" (the signal you're connecting to that port). The whitespace is just to improve readability.
dut: D_FF
port map (
D => D_s,
s => s_s,
CLOCK => CLOCK_s,
Q => Q_s
);
Named association port maps are much easier to debug, and the ports can be mapped in any order.

rising_edge(clk) not detecting edges when manually changing the clock value

I'm an amateur when it comes to VHDL and hardware in general but I've been working on a project for school and I came across something that I can't understand.
I have a register (type D FF) that's processing a clock signal to store the input value and, in simulation, it works fine if I use a "Force clock" in it's clk input but if I try to "simulate" a clock by manually changing it with "Force Constant" from zero to one and so forth it doesn't "pick up" on the rising edge.
Is this normal behavior? I assumed it would still detect the rising edge when going from 0 to 1.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity register_D is
generic (
WIDTH : POSITIVE := 1
);
Port ( CLK : in STD_LOGIC;
RST : in STD_LOGIC;
EN : in STD_LOGIC;
D : in STD_LOGIC_VECTOR(WIDTH-1 downto 0);
Q : out STD_LOGIC_VECTOR(WIDTH-1 downto 0));
end register_D;
architecture Behavioral of register_D is
begin
process (CLK, RST, EN)
begin
if (RST='1') then
Q <= (others=>'0');
elsif (rising_edge(CLK) and EN = '1') then
Q <= D;
end if;
end process;
end Behavioral;
Screenshot of me trying to trigger the FF by manually setting the clock (and not working):
Here you can see it working when I switch clk from "Force constant" to "Force clock":

VHDL Filter not getting output for first values

I tried implementing a fir filter in VHDL but during the first three clocks I get no output and the error at 0 ps, Instance /filter_tb/uut/ : Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)..
Source file (I also have 2 other files for D Flip-Flops):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
entity filter is
port ( x: in STD_LOGIC_VECTOR(3 downto 0);
clk: in STD_LOGIC;
y: out STD_LOGIC_VECTOR(9 downto 0));
end filter;
architecture struct of filter is
type array1 is array (0 to 3) of STD_LOGIC_VECTOR(3 downto 0);
signal coef : array1 :=( "0001", "0011", "0010", "0001");
signal c0, c1, c2, c3: STD_LOGIC_VECTOR(7 downto 0):="00000000";
signal s0, s1, s2, s3: STD_LOGIC_VECTOR(3 downto 0) :="0000";
signal sum: STD_LOGIC_VECTOR(9 downto 0):="0000000000";
component DFF is
Port ( d : in STD_LOGIC_VECTOR(3 downto 0);
clk : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(3 downto 0));
end component;
component lDFF is
Port ( d : in STD_LOGIC_VECTOR(9 downto 0);
clk : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(9 downto 0));
end component;
begin
s0<=x;
c0<=x*coef(0);
DFF1: DFF port map(s0,clk,s1);
c1<=s1*coef(1);
DFF2: DFF port map(s1,clk,s2);
c2<=s2*coef(2);
DFF3: DFF port map(s2,clk,s3);
c3<=s3*coef(3);
sum<=("00" & c0+c1+c2+c3);
lDFF1: lDFF port map(sum,clk,y);
end struct;
Testbench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use ieee.std_logic_unsigned.all;
ENTITY filter_tb IS
END filter_tb;
ARCHITECTURE behavior OF filter_tb IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT filter
PORT(
x : IN STD_LOGIC_VECTOR(3 downto 0);
clk : IN std_logic;
y : OUT STD_LOGIC_VECTOR(9 downto 0)
);
END COMPONENT;
--Inputs
signal x : STD_LOGIC_VECTOR(3 downto 0) := (others => '0');
signal clk : std_logic := '0';
--Outputs
signal y : STD_LOGIC_VECTOR(9 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: filter PORT MAP (
x => x,
clk => clk,
y => y
);
-- 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_proc1: process
begin
x<="0001";
wait for 10ns;
x<="0011";
wait for 10ns;
x<="0010";
wait for 10ns;
--x<="0011";
end process;
END;
Output:
If anyonce could help, I'd appreciate it. I think it has something to do with the inital values of the signals c_i and s_i but I'm not too sure.
Your FIR filter contains flip-flops. These flip-flops have no reset input and so power up in an unknown state. You simulator models this by initialising the flip-flops' outputs to "UUUU" (as the are four bits wide). A 'U' std_logic value represents and uninitialised value.
So, your code behaves as you ought to expect. If you're not happy with that behaviour, you need to add a reset input and connect it to your flip-flops.
You have build a series of three register making up a cascade of registers.
You have not provided a reset so the register contents will be Unknown. You use the registers for calculations without any condition. Thus you arithmetic calculations will see the Unknown values and fail as you have seen.
The first (simplest) solution would be to add a reset. But that is not the best solution. You will no longer get warnings but the first three cycles of your output will be based on the register reset value not of your input signal.
If you have a big stream and don't care about some incorrect values in the first clock cycle you can live with that.
The really correct way would be to have a 'valid' signal transported along side your data. You only present the output data when there is a 'valid'. This is the standard method to process data through any pipeline hardware structure.
By the way: you normally do not build D-ffs yourself. The synthesizer will do that for you. You just use a clocked process and process the data vectors in it.
I have some questions. If I add a reset pin, when will I toggle it from 1 to 0? How can I create this circuit without explicitly using D-ffs?
You make a reset signal in the same way as you make your clock.
As to D-registers: they come out if you use the standard register VHDL code:
reg : process (clk,reset_n)
begin
// a-synchronous active low reset
if (reset_n='0') then
s0 <= "0000";
s1 <= "0000";
s2 <= "0000";
elsif (rising_edge(clk)) then
s0 <= x;
s1 <= s0;
s2 <= s1;
....
(Code entered as-is, not checked for syntax or typing errors)

VHDL Testbench : Output not changing

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')

Implementing an Accumulator in VHDL

I am trying to implement a signed accumulator using Core Gen in Xilinx. According to my understanding an accumulator performs the function of a normal register which is just routing the input to the output, but I wanted clarification on that.
I added the Accumulator IPcore (.xco) module to the project and I have a main file which basically contains the component declaration and the port map. I have a single step process too. Everything compiles and I can see the result on the board but don't quite understand what's going on...
When I input 1000 the 8 bit output on the LEDs is 11111000. Another input of 1111 gives me 11110111. I am attaching the code here for the main vhd file called Accm and the .vho file.
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
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;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Accm is
port( b: in std_logic_vector(3 downto 0);
sclr, clk, b1, b2 : in std_logic;
q : out std_logic_vector(7 downto 0)
);
end Accm;
architecture Behavioral of Accm is
-- signal declaration
type tell is (rdy,pulse,not_rdy);
signal d_n_s: tell;
signal en: std_logic;
-- component declaration
COMPONENT my_accm
PORT (
b : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
clk : IN STD_LOGIC;
sclr : IN STD_LOGIC;
q : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
-- port map
begin
A1 : my_accm
PORT MAP (
b => b,
clk => en,
sclr => sclr,
q => q
);
process(clk)
begin
if clk'event and clk='1' then
case d_n_s is
when rdy => en <= '0';
if b1='1' then d_n_s <= pulse; end if;
when pulse => en <= '1';
d_n_s <= not_rdy;
when not_rdy => en <='0';
if b2='1' then d_n_s <= rdy; end if;
end case;
end if;
end process;
-- .VHO CODE
------------- Begin Cut here for COMPONENT Declaration ------ COMP_TAG
COMPONENT my_accm
PORT (
b : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
clk : IN STD_LOGIC;
sclr : IN STD_LOGIC;
q : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
-- COMP_TAG_END ------ End COMPONENT Declaration ------------
-- The following code must appear in the VHDL architecture
-- body. Substitute your own instance name and net names.
------------- Begin Cut here for INSTANTIATION Template ----- INST_TAG
your_instance_name : my_accm
PORT MAP (
b => b,
clk => clk,
sclr => sclr,
q => q
);
end Behavioral;
I am also pasting an image of the accumualtor I generated in CoreGen.
I'D appreciate it if someone could explain me what is going on in this program. Thanks!
"Accumulator" can mean many things. In the hardware Xilinx library, the component you instantiated is an adder in front of a register. The adder is adding the current value of the accumulator register with the input term. The accumulator register is wider than the input so you can accumulate (add together) many input terms without overflowing the output.
When your circuit starts, the accumulator contains zero. You input 1000 (-8) which when added to zero becomes 11111000 (-8 sign extended) on the output. You then add 1111 (-1), and the output becomes 11110111 (-9 sign extended).
Once you are done "accumulating", assert SCLR to clear the accumulator register back to zero (or use SSET or SINIT, as appropriate for your logic).
This should all be covered by the documentation for the Xilinx library (try clicking the "datasheet" button in the corgen dialog).
Actually, I think I get it now. It's just acting like an Adder with signed inputs. I think I am correct on this but would appreciate any clarification!

Resources