I have this vhdl code :
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity avalon_fir_4 is
port (
clk, reset: in std_logic;
-- avalon interface
gcd_address: in std_logic_vector(2 downto 0); -- 3-bit address
gcd_chipselect: in std_logic;
gcd_write: in std_logic;
gcd_writedata: in std_logic_vector(31 downto 0);
gcd_readdata: out std_logic_vector(31 downto 0));
end avalon_fir_4;
architecture arch of avalon_fir_4 is
signal i_coeff_0 : std_logic_vector( 31 downto 0);
signal i_coeff_1 : std_logic_vector( 31 downto 0);
signal i_coeff_2 : std_logic_vector( 31 downto 0);
signal i_coeff_3 : std_logic_vector( 31 downto 0);
-- data input
signal i_data : std_logic_vector( 31 downto 0);
-- filtered data
signal o_data : std_logic_vector( 31 downto 0);
signal wr_en, wr_a, wr_b, wr_c, wr_d, wr_e: std_logic;
type state_type is (idle, count);
signal state_reg, state_next: state_type;
signal c_reg, c_next: unsigned(15 downto 0);
begin
fir_unit: fir_filter_4 port map(clk, reset, i_coeff_0, i_coeff_1, i_coeff_2, i_coeff_3, i_data, o_data);
process (clk, reset)
begin
--if reset=’1’ then
--o_data <= (others=>(others=>'0'));
--data <= (others=>(others=>'0'));
--i_coeff_0 <= (others=>(others=>'0'));
--i_coeff_1 <= (others=>(others=>'0'));
--i_coeff_2 <= (others=>(others=>'0'));
--i_coeff_3 <= (others=>(others=>'0'));
--elsif (clk'event and clk=’1’) then
if wr_a=’1’ then
i_data <= gcd_writedata;
elsif wr_b=’1’ then
i_coeff_0 <= gcd_writedata;
elsif wr_c='1' then
i_coeff_1 <= gcd_writedata;
elsif wr_d='1' then
i_coeff_2 <= gcd_writedata;
elsif wr_e='1' then
i_coeff_3 <= gcd_writedata;
end if;
--end if;
end process;
wr_en <=’1’ when gcd_write=’1’ and gcd_chipselect=’1’ else ’0’;
wr_a <= ’1’ when gcd_address="000" and wr_en=’1’ else ’0’;
wr_b <= ’1’ when gcd_address="001" and wr_en=’1’ else ’0’;
wr_c <= ’1’ when gcd_address="010" and wr_en=’1’ else ’0’;
wr_d <= ’1’ when gcd_address="011" and wr_en=’1’ else ’0’;
wr_e <= ’1’ when gcd_address="100" and wr_en=’1’ else ’0’;
gcd_start <= ’1’ when gcd_address="010" and wr_en=’1’ else ’0’;
gcd_readdata <= r_out when gcd_address="100" else gcd_ready & "000" & x"000" & std_logic_vector(c_reg);
end arch;
compilation crash :
I have tried many ways of writing the vhdl at multiple places without success. What is this error?
Related
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;
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;
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.
Everything works but the increment function. It can increment from 0 to 1, 1 to 2, and then from 2 it goes to "1111111111". I'm stumped.
Variables:
D_IN: Data in
PC_OE: Active high. Drives PC_TRI output.
PC_LD: Active high synchronously loads D_IN into PC.
PC_INC: Active high synchronously increments value in PC.
RST: Active high asyncronous reset.
PC_COUNT: Current value in PC. Address.
PC_TRI: Current value in the PC under tri-state control. When PC_OE = '1', PC_TRI <=
PC_COUNT, else high impedance.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
entity ProgramCounter is
Port ( D_IN : in STD_LOGIC_VECTOR (9 downto 0);
PC_OE : in STD_LOGIC;
PC_LD : in STD_LOGIC;
PC_INC : in STD_LOGIC;
RST : in STD_LOGIC;
CLK : in STD_LOGIC;
PC_COUNT : out STD_LOGIC_VECTOR (9 downto 0);
PC_TRI : out STD_LOGIC_VECTOR (9 downto 0));
end ProgramCounter;
architecture Behavioral of ProgramCounter is
signal s_COUNT : STD_LOGIC_VECTOR (9 downto 0);
begin
s_COUNT <= "0000000000";
proc: process(RST, CLK, PC_LD, D_IN, s_COUNT, PC_INC, PC_OE)
begin
if (RST = '1') then
s_COUNT <= "0000000000";
elsif (rising_edge(CLK)) then
if (PC_LD = '1') then
s_COUNT <= D_IN;
elsif (PC_INC = '1') then
s_COUNT <= s_COUNT + 1;
else
end if;
else
end if;
if (PC_OE = '1') then
PC_TRI <= s_COUNT;
else
PC_TRI <= "ZZZZZZZZZZ";
end if;
PC_COUNT <= s_COUNT;
end process proc;
end Behavioral;
The comment of QuantumRipple is very useful
begin
--s_COUNT <= "0000000000";
...
I tried to comment such line and it worked.
Try to do this, and make RST before start to count
Please try this way and let me know, i corrected your code but I can't try it :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
entity ProgramCounter is
Port ( D_IN : in STD_LOGIC_VECTOR (9 downto 0);
PC_OE : in STD_LOGIC;
PC_LD : in STD_LOGIC;
PC_INC : in STD_LOGIC;
RST : in STD_LOGIC;
CLK : in STD_LOGIC;
PC_COUNT : out STD_LOGIC_VECTOR (9 downto 0);
PC_TRI : out STD_LOGIC_VECTOR (9 downto 0));
end ProgramCounter;
architecture Behavioral of ProgramCounter is
signal s_COUNT : STD_LOGIC_VECTOR (9 downto 0);
begin
proc: process(RST, CLK)
begin
if (RST = '1') then
s_COUNT <= "0000000000";
elsif (rising_edge(CLK)) then
if (PC_LD = '1') then
s_COUNT <= D_IN;
elsif (PC_INC = '1') then
s_COUNT <= s_COUNT + 1;
else
end if;
else
end if;
end process;
PC_TRI <= s_COUNT when (PC_OE = '1') else (others => 'Z');
PC_COUNT <= s_COUNT;
end Behavioral;
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;