Implementing a 10 bit shift register with led outputs - vhdl

I am trying to implement the the following shift register
entity MyShiftRegister is
port(
clock: in std_logic;
DataIn: in std_logic_vector (9 downto 0);
Left: in std_logic; --synchronous left rotate
Right: in std_logic; --synchronous right rotate
Load: in std_logic; --synchronous parallel load
Clear: in std_logic; -- synchronous clear
DataOut: out std_logic_vector (9 downto 0);
This is what I have so far
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity question2 is
Port (
led: buffer std_logic_vector (9 downto 0);
clk: in std_logic;
btnu: in std_logic;
btnL: in std_logic;
btnR: in std_logic ;
btnD: in std_logic;
btnC: in std_logic
);
end question2;
architecture Behavioral of question2 is
constant active: std_logic :='1';
constant inactive: std_logic :='0';
constant step_zero: std_logic_vector(9 downto 0) :="0000000000";
constant step_one: std_logic_vector(9 downto 0) :="0000000001";
constant step_two: std_logic_vector(9 downto 0) :="0000000010";
constant step_three: std_logic_vector(9 downto 0) :="0000000100";
constant step_four: std_logic_vector(9 downto 0) :="0000001000";
constant step_five: std_logic_vector(9 downto 0) :="0000010000";
constant step_six: std_logic_vector(9 downto 0) :="0000100000";
constant step_seven: std_logic_vector(9 downto 0) :="0001000000";
constant step_eight: std_logic_vector(9 downto 0) :="0010000000";
constant step_nine: std_logic_vector(9 downto 0) :="0100000000";
constant step_ten: std_logic_vector(9 downto 0) :="0100000000";
signal DataIn: std_logic_vector (9 downto 0):= "1111111111";
signal Load: std_logic := btnD;
signal Reset: std_logic;
signal Left: std_logic:= btnL;
signal Right: std_logic:= btnR;
signal DataOut: std_logic_vector := led (9 downto 0);
signal Clear: std_logic:= btnU;
signal speed_enable: std_logic;
begin
SpeedControl: process (clk)
variable counter: integer range 0 to 10000000;
begin
speed_enable<=not active;
if Reset = Active then
counter:= 0;
elsif (rising_edge (clk)) then
counter := counter + 1;
if (counter=10000000) then
speed_enable<= Active;
counter:=0;
end if;
end if;
end process;
shiftregister: process(clk, clear)
begin
if rising_edge (clk) then
if clear= active then
DataOut <= (others => '0');
elsif load = active then
DataOut <= DataIn ;
elsif Left = active then
DataOut <= DataOut(8 downto 0) & "1" ;
if DataOut = "1000000000" then
clear <= active;
elsif Right = active then
DataOut <= DataOut (9 downto 1) & "1" ;
if DataOut = "0000000001" then
clear <= active;
end if;
end if;
end if;
end if;
end process;
with DataOut select
led <= step_one when "0000",
step_two when "0001",
step_three when "0010",
step_four when "0011",
step_five when "0100",
step_six when "0101",
step_seven when "0110",
step_eight when "0111",
step_nine when "1000",
step_ten when "1001",
step_zero when others;
end Behavioral;
How exactly do I rotate bits left and right and tie that to my led outputs. I was thinking of using a counter and just incrementing and decrementing to shift bits left or right but I'm not sure if that would still be considered a shift register.
thanks

To start:
constant step_nine: std_logic_vector(9 downto 0) :="0100000000";
constant step_ten: std_logic_vector(9 downto 0) :="0100000000";
is incorrect. It should be
constant step_nine: std_logic_vector(9 downto 0) :="0100000000";
constant step_ten: std_logic_vector(9 downto 0) :="1000000000";
But this approach is very error prone anyhow. Lets simplify it:
process(sel)
variable selected_led : natural;
begin
led <= (others => '0');
selected_led := to_integer(unsigned(sel));
if selected_led < led'length then
led(selected_led) <= '1';
end if;
end process;
If the led(selected_led) <= '1'; won't synthesize, you probably have to change it to
for i in 0 to led'length-1 loop
if (i = selected_led) then
led(i) <= '1';
end if;
end loop;
As for using the buffer port. Don't. preferably only use in or out. If you want to read an out port, compile with VHDL-2008, or use a temporary signal in between.
Then note that right and left are keywords in VHDL. you shouldn't use them
What you want is very simple and basic VHDL. Example (using VHDL-2008):
process(clock)
begin
if rising'edge(clock) then
if clear = '1' then
data_out <= (others => '0');
elsif load = '1' then
data_out <= data_in;
elsif right_rotate = '1' then
data_out <= data_out(0) & data_out(data_out'length-1 downto 1);
elsif left_rotate = '1' then
data_out <= data_out(data_out'length-2 downto 0) &
data_out(data_out'length-1);
end if;
end if;
end process;

Related

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

i have a vhdl code that take a 16 bit binary converts it to 5 bcd(4bit) how can i connect each bcd with a display?

i have a code that take a 16 bit binary converts it to 5 bcd(4bit)
how can i connect each bcd with a display?
the bcd 0 has to connect to the display 0 (seven segment display) so that the binary number is going to convert to decimal and display it on 5 seven segment displays
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity binary_bcd is
generic(N: positive := 16);
port(
clk, reset: in std_logic;
binary_in: in std_logic_vector(N-1 downto 0);
bcd0, bcd1, bcd2, bcd3, bcd4: out std_logic_vector(3 downto 0)
);
end binary_bcd ;
architecture behaviour of binary_bcd is
type states is (start, shift, done);
signal state, state_next: states;
signal binary, binary_next: std_logic_vector(N-1 downto 0);
signal bcds, bcds_reg, bcds_next: std_logic_vector(19 downto 0);
-- output register keep output constant during conversion
signal bcds_out_reg, bcds_out_reg_next: std_logic_vector(19 downto 0);
-- need to keep track of shifts
signal shift_counter, shift_counter_next: natural range 0 to N;
begin
process(clk, reset)
begin
if reset = '1' then
binary <= (others => '0');
bcds <= (others => '0');
state <= start;
bcds_out_reg <= (others => '0');
shift_counter <= 0;
elsif falling_edge(clk) then
binary <= binary_next;
bcds <= bcds_next;
state <= state_next;
bcds_out_reg <= bcds_out_reg_next;
shift_counter <= shift_counter_next;
end if;
end process;
convert:
process(state, binary, binary_in, bcds, bcds_reg, shift_counter)
begin
state_next <= state;
bcds_next <= bcds;
binary_next <= binary;
shift_counter_next <= shift_counter;
case state is
when start =>
state_next <= shift;
binary_next <= binary_in;
bcds_next <= (others => '0');
shift_counter_next <= 0;
when shift =>
if shift_counter = N then
state_next <= done;
else
binary_next <= binary(N-2 downto 0) & 'L';
bcds_next <= bcds_reg(18 downto 0) & binary(N-1);
shift_counter_next <= shift_counter + 1;
end if;
when done =>
state_next <= start;
end case;
end process;
bcds_reg(19 downto 16) <= bcds(19 downto 16) + 3 when bcds(19 downto 16) > 4 else
bcds(19 downto 16);
bcds_reg(15 downto 12) <= bcds(15 downto 12) + 3 when bcds(15 downto 12) > 4 else
bcds(15 downto 12);
bcds_reg(11 downto 8) <= bcds(11 downto 8) + 3 when bcds(11 downto 8) > 4 else
bcds(11 downto 8);
bcds_reg(7 downto 4) <= bcds(7 downto 4) + 3 when bcds(7 downto 4) > 4 else
bcds(7 downto 4);
bcds_reg(3 downto 0) <= bcds(3 downto 0) + 3 when bcds(3 downto 0) > 4 else
bcds(3 downto 0);
bcds_out_reg_next <= bcds when state = done else
bcds_out_reg;
bcd4 <= bcds_out_reg(19 downto 16);
bcd3 <= bcds_out_reg(15 downto 12);
bcd2 <= bcds_out_reg(11 downto 8);
bcd1 <= bcds_out_reg(7 downto 4);
bcd0 <= bcds_out_reg(3 downto 0);
end behaviour;
test bench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY tb_bcd IS
END tb_bcd;
ARCHITECTURE behavior OF tb_bcd IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT binary_bcd
PORT(
clk : IN std_logic;
reset : IN std_logic;
binary_in : IN std_logic_vector(15 downto 0);
bcd0 : OUT std_logic_vector(3 downto 0);
bcd1 : OUT std_logic_vector(3 downto 0);
bcd2 : OUT std_logic_vector(3 downto 0);
bcd3 : OUT std_logic_vector(3 downto 0);
bcd4 : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal binary_in : std_logic_vector(15 downto 0) := (others => '0');
--Outputs
signal bcd0 : std_logic_vector(3 downto 0);
signal bcd1 : std_logic_vector(3 downto 0);
signal bcd2 : std_logic_vector(3 downto 0);
signal bcd3 : std_logic_vector(3 downto 0);
signal bcd4 : std_logic_vector(3 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: binary_bcd PORT MAP (
clk => clk,
reset => reset,
binary_in => binary_in,
bcd0 => bcd0,
bcd1 => bcd1,
bcd2 => bcd2,
bcd3 => bcd3,
bcd4 => bcd4
);
-- 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
-- hold reset state for 100 ns.
reset <= '1';
wait for 100 ns;
reset <= '0';
binary_in <= "0000000000001111";
wait for 200 ns;
binary_in <= "0000000001001111";
wait for 200 ns;
binary_in <= "0000000001111111";
wait for 200 ns;
binary_in <= "0000111101001111";
wait for 2000 ns;
end process;
END;

VHDL Testbench simulation only show three clk cycle

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

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