VHDL Testbench simulation only show three clk cycle - vhdl

THis is the vhdl code for a fir filter:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity FIR is
port(
CLK2: in std_logic;
Sendin : in std_logic;
Sendout: out std_logic;
Din : in std_logic_vector(11 downto 0);
Dout: out std_logic_vector(11 downto 0)
);
end FIR;
architecture Behavioral of FIR is
signal count : std_logic_vector(5 downto 0) := "000000";
signal send : std_logic := '0';
signal Dout_S : std_logic_vector(11 downto 0) := x"000";
type multype is array(36 downto 0) of std_logic_vector(23 downto 0);
signal mult : multype := ((others=> (others=>'0')));
type addtype is array(36 downto 0) of std_logic_vector(11 downto 0);
signal adder : addtype :=((others=> (others=>'0')));
type reg is array(36 downto 0) of std_logic_vector(11 downto 0);
signal shiftreg : reg:= ((others=> (others=>'0')));
signal coefs : reg:= (
x"015",x"02F",x"05E",x"0A8",x"114",x"1A8",x"268",x"356",x"472"
,x"5B6",x"71B",x"894",x"A10",x"B7E",x"CCC",x"DE6",x"EBD",x"F43"
,x"F71",x"F43",x"EBD",x"DE6",x"CCC",x"B7E",x"A10",x"894",x"71B"
,x"5B6",x"472",x"356",x"268",x"1A8",x"114",x"0A8",x"05E",x"02F"
,x"015"
);
begin
FIRcal:process(ClK2,Sendin)
begin
if rising_edge(clk2) then
count<=count + 1;
if Sendin = '1' then
shiftreg<=shiftreg(35 downto 0) & Din;
for I in 36 downto 0 loop
MULT(I) <= shiftreg(36-I) * COEFS(36-I);
if I = 0 then
ADDER(I) <= x"000" + ("000000" & MULT(I)(23 downto 17));
else
ADDER(I) <= ("000000" & MULT(I)(23 downto 17)) + ADDER(I-1);
end if;
end loop;
DOUT_S <= ADDER(36);
send <='1';
end if;
end if;
end process FIRcal;
--FIRsend: process(ClK2,Send)
--begin
--if rising_edge(clk2) then
--if send <= '1' then
-- send <='0';
--end if;
--end if;
--end process FIRsend;
Sendout <= Send;
Dout <= Dout_S;
end Behavioral;
Testbench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY fvfv IS
END fvfv;
ARCHITECTURE behavior OF fvfv IS
COMPONENT FIR
PORT(
CLK2 : IN std_logic;
Sendin : IN std_logic;
Sendout : OUT std_logic;
Din : IN std_logic_vector(11 downto 0);
Dout : OUT std_logic_vector(11 downto 0)
);
END COMPONENT;
--Inputs
signal CLK2 : std_logic := '0';
signal Sendin : std_logic := '0';
signal Din : std_logic_vector(11 downto 0) := (others => '0');
--Outputs
signal Sendout : std_logic;
signal Dout : std_logic_vector(11 downto 0);
-- Clock period definitions
constant CLK2_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: FIR PORT MAP (
CLK2 => CLK2,
Sendin => Sendin,
Sendout => Sendout,
Din => Din,
Dout => Dout
);
-- Clock process definitions
CLK2_process :process
begin
CLK2 <= '0';
wait for CLK2_period/2;
CLK2 <= '1';
wait for CLK2_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
Din <= x"0F0";
wait for 10 ns;
sendin<='1';
wait for 10 ns;
sendin<='0';
wait for 300 ns;
Din <= x"090";
sendin<='1';
wait for 10 ns;
sendin<='0';
end process;
END;
enter image description here
enter image description here
The testbench only show three clk cycles, I try to extend the time, but it didn't work, Is there any problem for my Code?

You have an error in follow lines:
if I = 0 then
ADDER(I) <= x"000" + ("00000" & MULT(I)(23 downto 17));
else
ADDER(I) <= ("00000" & MULT(I)(23 downto 17)) + ADDER(I-1);
end if;
As I told in comments you have different sizes of vectors.
To solve the issue you need to equate the sizes in depends on your logic (remove one 0 from right side or expand ADDER elements:
if I = 0 then
ADDER(I) <= x"000" + ("0000" & MULT(I)(23 downto 17));
else
ADDER(I) <= ("0000" & MULT(I)(23 downto 17)) + ADDER(I-1);
end if;
OR
type addtype is array(36 downto 0) of std_logic_vector(12 downto 0);
signal adder : addtype :=((others=> (others=>'0')));

Related

Unable to output data entered into a register

I have a simple program. I am trying to input the counter output into a memory address register and output the data that is in the memory address register.
Memory Address Register Code:
library ieee;
use ieee.std_logic_1164.all;
entity mar is
port(
mar_clk, mar_clr, mar_en : in std_logic;
mar_datain : in std_logic_vector(3 downto 0);
mar_dataout : out std_logic_vector(3 downto 0)
);
end entity;
architecture behavioral of mar is
begin
process(mar_clk, mar_clr, mar_en, mar_datain)
begin
if(mar_clr = '1') then
mar_dataout <= (others => '0');
elsif(mar_clk'event and mar_clk = '1') then
if(mar_en = '0') then
mar_dataout <= mar_datain;
end if;
end if;
end process;
end behavioral;
Buffer4 Code:
library ieee;
use ieee.std_logic_1164.all;
entity buffer4 is
port(
buff4_en : in std_logic;
datain : in std_logic_vector( 3 downto 0 );
dataout : out std_logic_vector( 3 downto 0 )
);
end entity;
architecture behavioral of buffer4 is
begin
process(buff4_en, datain)
begin
if(buff4_en = '1') then
dataout <= datain;
else
dataout <= (others => 'Z');
end if;
end process;
end behavioral;
Program Counter Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity pc is
port(
pc_ld, pc_en, pc_clk, pc_rst : in std_logic;
pc_datain : in std_logic_vector(3 downto 0);
pc_dataout : out std_logic_vector(3 downto 0)
);
end entity;
architecture behave of pc is
signal count : std_logic_vector(3 downto 0) := "0001";
signal temp : integer;
begin
process(pc_clk, pc_rst)
begin
if(pc_rst = '1') then
count <= (others => '0');
elsif(pc_clk'event and pc_clk = '1') then
if(pc_ld = '1') then
count <= pc_datain;
elsif(pc_en = '1') then
count <= count;
temp <= conv_integer(count);
if(temp = 16) then
count <= (others => '0');
end if;
count <= count + 1;
end if;
end if;
end process;
pc_dataout <= count;
end behave;
Test Program Code:
library ieee;
use ieee.std_logic_1164.all;
entity test is
end entity;
architecture behave of test is
component mar
port(
mar_clk, mar_clr, mar_en : in std_logic;
mar_datain : in std_logic_vector( 3 downto 0 );
mar_dataout : out std_logic_vector( 3 downto 0 )
);
end component;
component pc
port(
pc_ld, pc_en, pc_clk, pc_rst : in std_logic;
pc_datain : in std_logic_vector(3 downto 0);
pc_dataout : out std_logic_vector(3 downto 0)
);
end component;
component buffer4
port(
buff4_en : in std_logic;
datain : in std_logic_vector( 3 downto 0 );
dataout : out std_logic_vector( 3 downto 0 )
);
end component;
signal databus : std_logic_vector(7 downto 0);
signal addressbus : std_logic_vector(3 downto 0);
signal gclk : std_logic;
signal mar_clr, mar_en : std_logic;
signal pc_ld, pc_en, pc_rst : std_logic;
signal buff4_en : std_logic;
signal dataout : std_logic_vector(3 downto 0);
signal mar_datain, mar_dataout : std_logic_vector(3 downto 0);
signal pc_dataout : std_logic_vector(3 downto 0);
begin
U1 : pc port map(pc_ld, pc_en, gclk, pc_rst, databus(3 downto 0), pc_dataout);
U2 : buffer4 port map(buff4_en, pc_dataout, databus(3 downto 0));
U3 : mar port map(gclk, mar_clr, mar_en, databus(3 downto 0), addressbus);
stim_process : process
begin
gclk <= '0';
wait for 10 ns;
pc_ld <= '0';
pc_en <= '1';
pc_rst <= '0';
buff4_en <= '1';
mar_clr <= '0';
mar_en <= '0';
gclk <= '1';
wait for 10 ns;
gclk <= '0';
wait for 10 ns;
assert false report "Reached end of test. Start GTKWave";
wait;
end process;
end behave;
This is the output when I run the program
As seen the Memory Address Registers takes the input and doesn't output it on the address bus. How can I make the Memory Address Register output the data on the address bus?
This is the logic for writing to your memory address output register inside your 'MAR' component:
if(mar_clr = '1') then
mar_dataout <= (others => '0');
elsif(mar_clk'event and mar_clk = '1') then
if(mar_en = '0') then
mar_dataout <= mar_datain;
end if;
end if;
If appears that at your rising edge of clock (mar_clk'event and mar_clk = '1') in the waveforms that mar_clr and mar_en are both undefined U's. They have not got their values yet when the rising edge occurs.
You need to redo your testbench to make sure input signals are stable+defined before the rising edge so they are sampled correctly. Then mar_dataout <= mar_datain; should take correctly.
Could try moving initial wait statement like so:
gclk <= '0';
pc_ld <= '0';
pc_en <= '1';
pc_rst <= '0';
buff4_en <= '1';
mar_clr <= '0';
mar_en <= '0';
wait for 10 ns;
gclk <= '1';
wait for 10 ns;

LFSR doesn't generate random values during simulation

I am new to VHDL, but have some idea. I made this LFSR but don't know why it is stuck between the initial seed value and the other XOR value.
I am working with Altera Quartus 16 Lite and ISim.
library ieee;
use ieee.std_logic_1164.all;
--creating a galois LFSR
entity LFSR is
port (
clk : in std_logic;
rst : in std_logic;
en : in std_logic;
rdm_out : out std_logic_vector(15 downto 0);
rdm_out_a : out std_logic_vector(7 downto 0);
rdm_out_b : out std_logic_vector(7 downto 0);
lfsr_Done : out std_logic --lfsr done
);
end entity LFSR;
architecture behavioral of LFSR is
signal temp_out : std_logic_vector(15 downto 0) := (0 => '1' ,others => '0'); --initial value as seed
signal temp_done : std_logic;
begin
process (clk, rst)
begin
if rising_edge (clk) then --module operates only when enabled
if (rst = '1') then
temp_out <= (0 => '1' ,others => '0');
temp_done <= '0';
elsif (en = '1') then
temp_out <= temp_out(15 downto 11) & (temp_out(10) xor temp_out(0)) & temp_out(9 downto 5) & (temp_out(4) xor temp_out(0)) & temp_out(3 downto 0);
--temp_out <= (temp_out(15) xor temp_out(0)) & (temp_out(14) xor temp_out(0)) & temp_out(13) & (temp_out(12) xor temp_out(0)) & temp_out(11 downto 4) & (temp_out(3) xor temp_out(0)) & temp_out(2 downto 0);
temp_done <= '1';
end if;
end if;
end process;
rdm_out <= temp_out(15 downto 0);
rdm_out_a <= temp_out(15 downto 8);
rdm_out_b <= temp_out(7 downto 0);
lfsr_Done <= temp_done;
end architecture behavioral;`
The commented out temp_out is actual feedback (taps are 16,15,13, and 4) as I checked with random taps but still no improvement.
And the testbench I used is this:
library ieee;
use ieee.std_logic_1164.all;
entity lfsr_tb is
end lfsr_tb;
architecture test_bench of lfsr_tb is
component LFSR
port (
clk : in std_logic;
rst : in std_logic;
en : in std_logic;
rdm_out : out std_logic_vector(15 downto 0);
rdm_out_a : out std_logic_vector(7 downto 0);
rdm_out_b : out std_logic_vector(7 downto 0);
lfsr_Done : out std_logic );
end component;
signal clk1: std_logic;
signal rst1: std_logic;
signal en1 : std_logic;
signal rdm_out1 : std_logic_vector(15 downto 0);
signal rdm_out_a1 : std_logic_vector(7 downto 0);
signal rdm_out_b1 : std_logic_vector(7 downto 0);
signal lfsr_Done1 : std_logic ;
begin
mapping: LFSR port map(
clk => clk1,
rst => rst1,
en => en1,
rdm_out => rdm_out1,
rdm_out_a => rdm_out_a1,
rdm_out_b => rdm_out_b1,
lfsr_Done => lfsr_Done1 );
clock: process
begin
clk1 <= '0'; wait for 10 ps;
clk1 <= '1'; wait for 10 ps;
end process;
reset: process
begin
rst1 <= '1'; wait for 10 ps;
rst1 <= '0';
en1 <= '1'; wait for 800 ps;
end process;
end test_bench;
This is the result I am getting:
Yes it was not shifting but this is one is working now.
temp_out(15) <= temp_out(0);-- shifting bit
temp_out(14) <= temp_out(15);
temp_out(13) <= temp_out(14) xor temp_out(0);
temp_out(12) <= temp_out(13) xor temp_out(0);
temp_out(11) <= temp_out(12);
temp_out(10) <= temp_out(11) xor temp_out(0);
temp_out(9 downto 0) <= temp_out(10 downto 1);
Hope it helps others. Thanks guys

Can't get VHDL Sequential Multiplier to Multiply correctly

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.

State_Machine VHDL Code, can you please check why it doesn't work ! it synthesises ok

i have an assignment to write a state machine in VHDL to take control of a small built MC ( consists of 4 flip-flops,2 MUX4to1, MUX1to4, ROM, ALU,Inport ).
i have written different codes and tried several methods however simulating it shows no results, i get 'U' for results.
Code below, please check for obvious errors which I've probably missed.
i think the problem is that the stjatemachine doesn't transition through the states or doesn't execute the code inside each state.
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 07:48:47 10/26/2014
-- Design Name:
-- Module Name: STATE_MACHINE - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.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 STATE_MACHINE is
port (
--General Ports
CLK : in STD_LOGIC;
Re_Run_Programme : in STD_LOGIC;
--Process A parts
Programme_Start : in STD_LOGIC;
Data_From_ROM : in STD_LOGIC_VECTOR(7 downto 0);
ADDR_To_ROM : out STD_LOGIC_VECTOR (5 downto 0);
Programme_Status: out STD_LOGIC;
EN_OUT : out STD_LOGIC;
--Process B Part
--Process C Parts
MUX_FF_Select : out STD_LOGIC_VECTOR (1 downto 0);
MUX1_Select : out STD_LOGIC_VECTOR(1 downto 0);
MUX2_Select : out STD_LOGIC_VECTOR(1 downto 0);
ALU_Select : out STD_LOGIC_VECTOR(1 downto 0);
EN_A_Ports : out STD_LOGIC;
EN_B_Ports : out STD_LOGIC;
BUS_Select : out STD_LOGIC_VECTOR (1 downto 0);
Reset : out STD_LOGIC
);
end STATE_MACHINE;
architecture Behavioral of STATE_MACHINE is
type State_Type is (State_A,State_B,State_C,State_D);
signal State,Next_State : State_Type;
signal Counter : STD_LOGIC_VECTOR(5 downto 0);
--signal MO_A : STD_LOGIC;
--signal MO_B : STD_LOGIC;
--signal MO_C : STD_LOGIC;
--signal MO_D : STD_LOGIC;
signal FF_Instruction : STD_LOGIC_VECTOR (7 downto 0); -- 00
signal MUX_ALU_Instruction : STD_LOGIC_VECTOR (7 downto 0); -- 01
signal BUS_A_B_Ports_Instruction : STD_LOGIC_VECTOR (7 downto 0); -- 10
signal Reset_Instruction : STD_LOGIC_VECTOR (7 downto 0);
signal FF_Path : STD_LOGIC;
signal MUX_ALU_Path : STD_LOGIC;
signal BUS_A_B_Ports_Path : STD_LOGIC;
signal Reset_Path : STD_LOGIC;
signal EN_OUT_reg : STD_LOGIC;
--signal Next_Call : STD_LOGIC_VECTOR (7 downto 0);
signal Instruction_Finder : STD_LOGIC_VECTOR (7 downto 0);
signal Instruction_Identifier : STD_LOGIC_VECTOR(7 downto 0);
signal Instruction : STD_LOGIC_VECTOR(7 downto 0);
signal Call_Next_Instruction : STD_LOGIC_VECTOR(5 downto 0);
begin
FF_Instruction <= "00000000";
MUX_ALU_Instruction <= "01000000";
BUS_A_B_Ports_Instruction <= "10000000";
Reset_Instruction <= "11000000";
Instruction_Finder <= "11000000";
Counter <= "000000";
Call_Next_Instruction <= "000000";
--Re Run the programme
Process(CLK)
begin
if rising_edge(CLK) then
if (Re_Run_Programme = '1') then
State <= State_A;
-- MO_A <= '0';
else
State <= Next_State;
end if;
end if;
end Process;
--next state
Process(CLK,State)
begin
Next_State <= State;
case State is
--#### STATE A #####
when State_A =>
--if falling_edge(CLK) then
ADDR_To_ROM <= Call_Next_Instruction;
--EN_OUT <= '1';
--if falling_edge (CLK) then
--Instruction <= DATA_From_ROM;
--end if;
Next_State <= State_B;
--end if;
--#### STATE B #####
when State_B =>
EN_OUT <= '1';
Instruction <= DATA_From_ROM;
Instruction_Identifier <= (Instruction and Instruction_Finder);
case (Instruction_Identifier) is
when "00000000" => FF_Path <= '1';
when "01000000" => MUX_ALU_Path <= '1';
when "10000000" => BUS_A_B_Ports_Path <= '1';
when "11000000" => Reset_Path <= '1';
when others => null;
end case;
Next_State <= State_C after 40ns;
--#### STATE C #####
when State_C =>
--########
if ((FF_Path = '1') and (Counter = 2)) then
MUX_FF_Select <= "00";
end if;
if ((FF_Path = '1') and (Counter = 4)) then
MUX_FF_Select <= "00" after 20ns;
end if;
--########
if (falling_edge(CLK) and (MUX_ALU_Path = '1')) then
MUX1_Select <= "00";
MUX2_Select <= "00";
end if;
--########
if ( rising_edge(CLK) and BUS_A_B_Ports_Path = '1') then
if Counter = 1 then
BUS_Select <= "01";
end if;
if Counter = 3 then
BUS_Select <= "10";
end if;
EN_A_Ports <= '1';
EN_B_Ports <= '1';
end if;
--########
if ( rising_edge(CLK) and Reset_Path = '1') then
Reset <= '1';
end if;
Next_State <= State_D after 60ns;
--#### STATE D #####
when State_D =>
EN_OUT <= '0';
Counter <= Counter + 1;
if Counter > 5 then
Next_State <= State_D;
end if;
Call_Next_Instruction <= Counter;
Next_State <= State_A;
end case;
end process;
end Behavioral;
github link to code: https://github.com/quasarMind/StateMachine.git
Besides comments by Bill Lynch and Brian Drummond addressing synthesis eligibility a reason why the model gets all 'U's appears to revolve around multiple drivers for
Instruction_Finder, Counter and Call_Next_Instruction. One driver is initialized the other delivering all 'U's, the two resolve to all 'U's.
For purposes of simulating to see what your state machine actually does (and sidestepping the issue of synthesis), set default values for these three signals in their declarations and comment out the additional concurrent signal assignment statements, e.g.:
signal Counter : STD_LOGIC_VECTOR(5 downto 0) := (others => '0');
signal Instruction_Finder : STD_LOGIC_VECTOR (7 downto 0) := "11000000";
signal Call_Next_Instruction : STD_LOGIC_VECTOR(5 downto 0) := (others => '0');
-- Instruction_Finder <= "11000000";
-- Counter <= "000000";
-- Call_Next_Instruction <= "000000";
Most synthesis vendors will honor default values for signals for FPGA targets, otherwise you can add a reset.

VHDL - Writing to FPGA Register

I have an FPGA with four push buttons - the two left most ones should cycle up and down the 16 registers, while the two right most ones should increment and decrement the value stored in this register. Here is my attempt at the code to do this:
entity raminfr is --inferring the RAM here
port (
clk : in std_logic;
we : in std_logic;
a : in unsigned(3 downto 0);
di : in unsigned(7 downto 0);
do : out unsigned(7 downto 0)
);
end raminfr;
architecture rtl of raminfr is
type ram_type is array (0 to 15) of unsigned(7 downto 0);
signal RAM : ram_type;
signal read_a : unsigned(3 downto 0);
begin
U1: entity work.lab1 port map ( --ERROR ON THIS LINE
register_counter => a,
value_counter => di
);
process (clk)
begin
if rising_edge(clk) then
if we = '1' then
RAM(to_integer(a)) <= di;
end if;
read_a <= a;
end if;
end process;
do <= RAM(to_integer(read_a));
end rtl;
--lab1 starts here
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity lab1 is
port(
clock : in std_logic;
key : in std_logic_vector(3 downto 0);
value_counter : out unsigned(7 downto 0) ; --value to be written to register
register_counter : out unsigned(3 downto 0) --register to write value to
);
end lab1;
architecture up_and_down of lab1 is --actual button logic here
begin
process(clock)
begin
if rising_edge(clock) then
if (key(3)='0' and key(2)='0' and key(1)='1' and key(0)='0') then
value_counter <= value_counter + "1";
elsif (key(3)='0' and key(2)='0' and key(1)='0' and key(0)='1') then
value_counter <= value_counter - "1";
elsif (key(3)='1' and key(2)='0' and key(1)='0' and key(0)='0') then
register_counter<= register_counter + "1";
elsif (key(3)='0' and key(2)='1' and key(1)='0' and key(0)='0') then
register_counter<= register_counter - "1";
end if;
end if;
end process;
end architecture up_and_down;
I get the error Error (10577): VHDL error at DE2_TOP.vhd(312): actual port "a" of mode "in" cannot be associated with formal port "register_counter" of mode "out"on the line indicated above. It is obvious this is not how I would go about doing what I want to do. Can someone shed some light on this?
Change your point of view: Put the RAM under the Pushbutton-FSM. Not vice versa.
This RAM description should be synthesiable. If not take a look in the Synthesis Guide of your tool vendor.
entity raminfr is --inferring the RAM here
port (
clk : in std_logic;
we : in std_logic;
a : in unsigned(3 downto 0);
di : in unsigned(7 downto 0);
do : out unsigned(7 downto 0)
);
end entity raminfr;
architecture rtl of raminfr is
type ram_type is array (0 to 15) of unsigned(7 downto 0);
signal RAM : ram_type;
begin
process (clk)
begin
if rising_edge(clk) then
if we = '1' then
RAM(to_integer(a)) <= di;
end if;
do <= RAM(to_integer(a));
end if;
end process;
end architecture rtl;
You also forgot to activate the write enable for the RAM.
Maybe you try this code (Always do a simulation first!):
--lab1 starts here
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity lab1 is
port(
clock : in std_logic;
key : in std_logic_vector(3 downto 0);
value_counter : out unsigned(7 downto 0); --value to be written to register
ram_data : out unsigned(7 downto 0); --value from 'RAM-register'
register_counter : out unsigned(3 downto 0) --register to write value to
);
end lab1;
architecture up_and_down of lab1 is --actual button logic here
signal value : unsigned(7 downto 0) := (others => '0');
signal ram_a : unsigned(3 downto 0) := (others => '0');
signal ram_we : std_logic;
begin
-- infer your RAM
your_ram: entity work.raminfr
port map (
clk => clock, --: in std_logic;
we => ram_we, --: in std_logic;
a => ram_a, --: in unsigned(3 downto 0);
di => value, --: in unsigned(7 downto 0);
do => ram_data --: out unsigned(7 downto 0)
);
process(clock)
begin
if rising_edge(clock) then
-- default
ram_we <= '0';
-- change value
if key(1) = '1' then
value <= value + 1;
end if;
-- change value
if key(0) = '1' then
value <= value - 1;
end if;
-- change 'register'
if key(3) = '1' then
ram_a <= ram_a + 1;
end if;
-- write value to register
if key(2) = '1' then
ram_we <= '1';
end if;
end if;
end process;
value_counter <= value;
register_counter <= ram_a;
end architecture up_and_down;

Resources