VHDL FSM Implementation using port mapping - vhdl

I'm trying to implement VHDL code using Finite state machine and Port mapping to components
Does any one have an idea how to do it, since it isn't allowed to include the port mapping inside the process statement?
------ and_2.vhd (component): ---------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
---------------------------------------
ENTITY and_2 IS
PORT ( a, b: IN STD_LOGIC;
y:OUT STD_LOGIC);
END and_2;
---------------------------------------
ARCHITECTURE and_2 OF and_2 IS
BEGIN
y <= a AND b;
END and_2;
---------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE work.my_data.all;
ENTITY FSM_PORTMAPP IS
PORT(
clk,reset : IN STD_LOGIC;
A,b,c,d: IN STD_LOGIC;
x: out STD_LOGIC
);
END FSM_PORTMAPP;
ARCHITECTURE Flow OF FSM_PORTMAPP IS
-----------------------
COMPONENT and_2 IS
PORT ( a, b: IN STD_LOGIC; y: OUT STD_LOGIC);
END COMPONENT;
-----------------------
TYPE state IS (state0, state1, state2);
SIGNAL pr_state, nx_state: state;
signal y,z :std_logic;
BEGIN
U1:and_2 PORT MAP(a,b ,y);
U2:and_2 PORT MAP(c,d,z);
U3:and_2 PORT MAP(y,z,x);
process(clk,reset)
BEGIN
IF (reset='1') THEN
pr_state <= state0;
ELSIF (clk'EVENT AND clk='1') THEN
pr_state <= nx_state;
END IF;
end process;
process(pr_state)
BEGIN
case pr_state IS
WHEN state0 =>
nx_state <= state1;
WHEN state1=>
nx_state <= state2;
WHEN state2 =>
nx_state <= state0;
END CASE;
end process;
END Flow;
-------------------------------------------------
That is an example for declaration, I want to implement three states, with each state implementing one component.

First of all, think of component instantiation and port mapping as wiring circuit components, not performing operations. The mapping itself does not perform any operation - the logic in the component combined with the signals driven into the component achieve that. This is also why you can't map a component in a process - wiring is a fixed connection, not something that you can perform as a runtime operation. It's not executed code - it's concurrent logic.
In your example code, there are three instances of the component and_2, outside of any process. This mapping is basically what you need (provided you change the component and signal types to your particular function). Then, in your state machine, you can drive the inputs selectively, or read the outputs, or whatever you need. You will probably need some intermediate signals, and you would need to change your wiring around, and what you will most likely get on your first attempt is problematic code with latches where you don't want them and nice things like that. What you can do instead is just register the adder outputs:
U1 : adder_2 port map (a, b, y);
U2 : adder_2 port map (c, d, z);
U3 : adder_2 port map (y_r, z_r, x);
adder_regs : process (clk)
begin
if rising_edge(clk) then
y_r <= y;
z_r <= z;
end if;
end process adder_regs;
Or is there some other reason you're trying to do it the way you are?

Related

D flip-flop synthesizable

I want to make a D ff with a little delay on the reset, D will always be '1', clk will be controlled by a switch(it will give a command for a specific floor on an elevator) and count_aux will be a 1Hz clock, but when I try to synthesize it shows me this error "ERROR:Xst:1534 - Sequential logic for node appears to be controlled by multiple clocks.". I don't want to clk to be understood as a clock, since it will be just a switch. How can I do that?
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity D_FF is
port ( D: in std_logic;
clk: in std_logic;
count_aux: in std_logic;
reset: in std_logic;
Q: out std_logic:='0'
);
end D_FF;
architecture a1 of D_FF is
signal i: std_logic_vector(3 downto 0):="0000";
begin
proc: process (D,clk,reset)
begin
if (reset='1') then
if(count_aux'event and count_aux='1') then i<=i+1;
if (i="0001") then
q<='0';
i<="0000";
end if;
end if;
elsif (clk'event and clk='1') then
q<=d;
end if;
end process proc;
end a1;
You are using clk as a clock in the process, so it will be a clock ;) But the weird thing for the synthesis is that you want to have a clocked flipflop (sequential element or regeister or what ever) but yet you also include combinatorial logic into the reset. So it has no idea what to synthesize since it has no component in the library for this logic.
So my advise is to keep the sequential and combinatorial logic separate. Sequential logic will have only clk and reset in the sensitivity list and have the code structure of:
process(clk, reset)
begin
if reset = 1 then
foobar <= '0';
elsif rising_edge(clk) then
foobar <= foo + bar;
end if;
end process;

VHDL MUX Test Bench Issue

I'm trying to learn VHDL through P. Ashenden's book: Designer's Guide to VHDL. Chapter one's exercise 10 asks you to write 2-to-1 (I'm assuming 1 bit wide) MUX in VHDL and simulate it. I apologize in advance for being a complete noob. This is my first VHDL code.
My MUX didn't produce any errors or warnings in synthesis. My test bench doesn't produce errors or warnings, either. However, the simulation comes up completely blank, except for the names of the signals.
I've tried looking at a multitude of other MUX examples online (as well as a bench test example from the book), all of which gave errors when I tried sythesizing them, so I wasn't confident enough to use them as guides and didn't get much out of them. I'm not sure what I'm doing wrong here. I'd include an image of the simulation, but I don't have enough rep points :(
Also, I realize that a good MUX should also have cases for when it receives no select input/high impedance values, ect.. In this case, I'm just trying to get the toy model working.
The MUX code is:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity MUXtop is
Port (a, b, sel: in bit;
z: out bit);
end MUXtop;
architecture behav of MUXtop is
begin
choose: process is
begin
if sel = '0' then
z <= b;
else
z <= a;
end if;
end process choose;
end architecture behav;
The test bench code is:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY MUXtest IS
END MUXtest;
ARCHITECTURE behavior OF MUXtest IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT MUXtop
PORT(
a : IN bit;
b : IN bit;
sel : IN bit;
z : OUT bit
);
END COMPONENT MUXtop;
--Inputs
signal a : bit := '0';
signal b : bit := '0';
signal sel : bit := '0';
--Outputs
signal z : bit;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: MUXtop PORT MAP (
a => a,
b => b,
sel => sel,
z => z
);
-- Stimulus process
stimulus: process
begin
wait for 10 ns;
a <= '1';
wait for 10 ns;
sel <= '1';
wait for 10 ns;
b <= '1';
wait;
end process stimulus;
END architecture behavior;
You don't need a use clause for package std_logic_1164 when using type bit (declared in package standard).
Your process statement choose in MUXtop has no sensitivity clause which cause the process to continually execute in simulation. (It won't do anything until you trip over a delta cycle iteration limit which might be set to infinity).
I added a sensitivity list, commented out the superfluous use clauses in the two design units and added some more stimulus steps as well as a final wait for 10 ns; to allow the last action to be seen in your testbench:
library IEEE;
-- use IEEE.STD_LOGIC_1164.ALL;
entity MUXtop is
Port (a, b, sel: in bit;
z: out bit);
end MUXtop;
architecture behav of MUXtop is
begin
choose: process (a, b, sel) -- is
begin
if sel = '0' then
z <= b;
else
z <= a;
end if;
end process choose;
end architecture behav;
LIBRARY ieee;
-- USE ieee.std_logic_1164.ALL;
ENTITY MUXtest IS
END MUXtest;
ARCHITECTURE behavior OF MUXtest IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT MUXtop
PORT(
a : IN bit;
b : IN bit;
sel : IN bit;
z : OUT bit
);
END COMPONENT MUXtop;
--Inputs
signal a : bit := '0';
signal b : bit := '0';
signal sel : bit := '0';
--Outputs
signal z : bit;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: MUXtop PORT MAP (
a => a,
b => b,
sel => sel,
z => z
);
-- Stimulus process
stimulus: process
begin
wait for 10 ns;
a <= '1';
wait for 10 ns;
sel <= '1';
wait for 10 ns;
sel <= '0'; -- added
wait for 10 ns; -- added
b <= '1';
wait for 10 ns; -- added
wait;
end process stimulus;
END architecture behavior;
And that gives:
(clickable)

pseudorandom pattern generator, output is not changing

I am using modelsim for simulating a pseudo-random pattern generator using the below code. The problem is when i force the data_reg signal to a seed value (ex: 0001010101101111) the data_out shows the same value instead of a random value. i will really appreciate any help i cud get on this one.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity dff is
Port ( CLK : in std_logic;
RSTn : in std_logic;
D : in std_logic;
Q : out std_logic);
end dff;
architecture Behavioral of dff is
begin
process(CLK)
begin
if CLK'event and CLK='1' then
if RSTn='1' then
Q <= '1';
else
Q <= D;
end if;
end if;
end process;
end Behavioral;
VHDL CODE FOR PRBS Generator using LFSR:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity lfsr is
Port ( CLK : in STD_LOGIC;
RSTn : in STD_LOGIC;
data_out : out STD_LOGIC_VECTOR (15 downto 0));
end lfsr;
architecture Behavioral of lfsr is
component dff
Port ( CLK : in std_logic;
RSTn : in std_logic;
D : in std_logic;
Q : out std_logic);
end component;
signal data_reg : std_logic_vector(15 downto 0);
signal tap_data : std_logic;
begin
process(CLK)
begin
tap_data <= (data_reg(1) xor data_reg(2)) xor (data_reg(4) xor
data_reg(15));
end process;
stage0: dff
port map(CLK, RSTn, tap_data, data_reg(0));
g0:for i in 0 to 14 generate
stageN: dff
port map(CLK, RSTn, data_reg(i), data_reg(i+1));
end generate;
data_out <= data_reg after 3 ns;
end Behavioral;
First off. In your LFSR you have a process sensitive to CLK which should only be combinational:
process(CLK) -- Not correct
-- Change to the following (or "all" in VHDL-2008)
process(data_reg)
You could also just implement it as a continuous assignment outside of a formal process which is functionally the same in this case.
When you force data_reg to a value you are overriding the normal signal drivers instantiated in the design. In the GUI the force command defaults to "Freeze". Once that is in place, the drivers can't update data_reg because the freeze force is dominant until you cancel it. In the force dialog select the "Deposit" kind to change the state without overriding the drivers on subsequent clocks.
The Modelsim documentation has this to say about the different force kinds:
freeze -- Freezes the item at the specified value until it is forced again or until it is unforced with a noforce command.
drive -- Attaches a driver to the item and drives the specified value until the item is forced again or until it is unforced with a noforce command. This option is illegal for unresolved signals.
deposit -- Sets the item to the specified value. The value remains until there is a subsequent driver transaction, or until the item is forced again, or until it is unforced with a noforce command
Note: While a lot of instructional materials (unfortunately) demonstrate the use of the std_logic_arith and std_logic_unsigned libraries, these are not actual IEEE standards and shouldn't be used in standard conformant VHDL. Use numeric_std instead or, in your case, just eliminate them since you aren't using any arithmetic from those libraries.

port map in structural VHDL code

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.

Binary serial adder - VHDL

I'm trying to design a 32bit binary serial adder in VHDL, using a structural description. The adder should make use of a full adder and a d-latch. The way I see it is:
Full adder:
architecture Behavioral of FullAdder is
begin
s <= (x xor y) xor cin;
cout <= (x and y) or (y and cin) or (x and cin);
end Behavioral;
D-Latch:
architecture Behavioral of dLatch is
begin
state: process(clk)
begin
if(clk'event and clk = '1') then
q <= d;
end if;
end process;
end Behavioral;
Serial adder:
add: process ( clk )
variable count : integer range 0 to 31;
variable aux : STD_LOGIC;
variable aux2 : STD_LOGIC;
begin
if(clk'event and clk = '1') then
fa: FullAdder port map(x(count), y(count), aux, s(count), aux2);
dl: dLatch port map(clock, aux2, aux);
count := count + 1;
end if;
end process;
However, it doesn't seem to work.
Also, what would be the simplest way to pipeline the serial adder?
"It doesn't seem to work" is pretty general, but one problem I see is that you are trying to instantiate the component fa: FullAdder within a process. Think about what component instantiation means in hardware, and you will realize that it makes no sense to instantiate the module on the rising_edge of clk...
Move the instantiation out of the process, and it should at least remove the syntax error you should be seeing ("Illegal sequential statement." in ModelSim).
For pipelining the serial adder, the best way is to connect the adders and d flip-flops one after the other. So, you would have the cout of the first adder be the input of a flip-flop. The output of that flip-flop will be the cin of the next adder and so on. Be careful though, because you will also have to pipeline the s of each adder, as well as each bit of the input, by essentially putting several d flip-flops in a row to copy them through the various pipeline stages.

Resources