VHDL-can't add numbers? - vhdl

Hello I want to build a clock on my ALTERA DE2 that I can adjust the length of by pressing keys.
Now the problem is that when I convert from STD_LOGIC_VECTOR to UNSIGNED the code does not work:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--use ieee.std_logic_unsigned.all; Do not use with numeric_std
entity Adjust_Clock_4_buttens is
port(
clk,clk1 : in STD_LOGIC;
minutes_plus, minutes_minus,houres_plus,houres_minus : in STD_LOGIC;
minutes : IN STD_LOGIC_VECTOR(5 downto 0);
houres : IN STD_LOGIC_VECTOR(4 downto 0);
output_minutes : out STD_LOGIC_VECTOR(5 downto 0);
output_houres : out STD_LOGIC_VECTOR(4 downto 0);
LED_0 : OUT STD_LOGIC;
LED_1 : OUT STD_LOGIC;
LED_2 : OUT STD_LOGIC;
LED_3 : OUT STD_LOGIC
);
end entity Adjust_Clock_4_buttens ;
architecture behavioral of Adjust_Clock_4_buttens is
signal button1_r : std_logic_vector(2 downto 0);
signal button2_r : std_logic_vector(2 downto 0);
signal button3_r : std_logic_vector(2 downto 0);
signal button4_r : std_logic_vector(2 downto 0);
-- signal minutes_total : unsigned(5 downto 0) := (others => '0');
-- signal houres_total : unsigned(4 downto 0) := (others => '0');
signal minutes_total : unsigned(5 downto 0);
signal houres_total : unsigned(4 downto 0);
begin
process(clk)
begin
if (rising_edge(clk) )then
minutes_total<=unsigned(minutes);
houres_total<=unsigned(houres);
-- Shift the value of button in button_r
-- The LSB is unused and is there solely for metastability
button1_r <= button1_r(button1_r'left-1 downto 0) & minutes_plus;
button2_r <= button2_r(button2_r'left-1 downto 0) & minutes_minus;
button3_r <= button3_r(button3_r'left-1 downto 0) & houres_plus;
button4_r <= button4_r(button4_r'left-1 downto 0) & houres_minus;
if button1_r(button1_r'left downto button1_r'left-1) = "01" then -- Button1 rising --button1_r[2:1]
minutes_total <= (minutes_total + 1);
LED_0<='1';LED_1<='0';LED_2<='0';LED_3<='0';
elsif button2_r(button2_r'left downto button2_r'left-1) = "01" then -- Button2 rising --button1_r[2:1]
minutes_total <= (minutes_total-1 );
LED_0<='0';LED_1<='1';LED_2<='0';LED_3<='0';
end if;
if button3_r(button3_r'left downto button3_r'left-1) = "01" then -- Button1 rising --button1_r[2:1]
houres_total <= (houres_total + 1);
LED_0<='0';LED_1<='0';LED_2<='1';LED_3<='0';
elsif button4_r(button4_r'left downto button4_r'left-1) = "01" then -- Button2 rising --button1_r[2:1]
houres_total<= (houres_total-1 );
LED_0<='0';LED_1<='0';LED_2<='0';LED_3<='1';
end if;
end if;
end process;
output_minutes <= std_logic_vector(minutes_total);
output_houres <= std_logic_vector(houres_total);
end architecture behavioral ;
So in this code I get the time from another block the problem start when I try to add minutes and hours and for some reason it does not react to pressing of the keys. Could anyone explain maybe why is that?

The problem might be that you only have the clock in the sensitivity list of your process. Try adding the buttons in the sensitivity list, since they drive your if conditions. (Not sure if that's the problem but I guess it's worth a try)

minutes_total<=unsigned(minutes);
is on 2 lines, inside and outside of the process, which generates multiple line drivers, and will not work, ever!
(didn't read the rest of the code, there may be other problems, like hours not taking an e)
Now that it's inside the process, you need to rename minutes_total as minute_source, else you're incrementing the value only for the one clock cycle when you have a button edge!

Related

Can't resolve multiple constant drivers for net

I wrote this code. I want to count the numbers that I pressed they key_0 and if I press 2 times then the red led will turn on, how ever I get this error:
Can't resolve multiple constant drivers for net.
The thing is that I try to torn on 2 process at the same time how ever this tow process have the same variable: duty_cycle_counter.
What is the problem?
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity Pwm_control is
generic(display_resolution : INTEGER := 8);
port(
key_0 : in BIT;
green_led : out BIT;
red_led : out BIT
);
end Pwm_control;
architecture Behavioral of Pwm_control is
signal counter : std_logic_vector(display_resolution downto 0);
signal general_counter : std_logic_vector(23 downto 0); -- general_counter is for the clock divider , can get till 23
signal step_10_dc : STD_LOGIC_VECTOR(8 downto 0); --10 step PWM
signal step_5_dc : STD_LOGIC_VECTOR(8 downto 0); --5 step PWM
signal starting_value_0 : STD_LOGIC_VECTOR(8 downto 0); --0 step PWM
signal duty_cycle_counter : STD_LOGIC_VECTOR(8 downto 0);
begin
starting_value_0 <= "000000000";
step_5_dc <= "000011010";
step_10_dc <= "000110011";
duty_cycle_counter <= "000000000";
key_testing : process(key_0) --
begin
if (key_0 = '0') then
green_led <= '1';
duty_cycle_counter <= (duty_cycle_counter + step_5_dc);
else
green_led <= '0';
end if;
end process key_testing;
key_test_red_led : process(duty_cycle_counter)
begin
if (step_10_dc <= duty_cycle_counter) then
red_led <= '1';
end if;
end process key_test_red_led;
end Behavioral;
You're driving duty_cycle_counter continuously with 0 and trying to update it in the key_testing process. It looks like you wanted a start value (possible in most RAM-based FPGAs) or a reset, though in real life it will have some value so you could just leave out the initialization.

VHDL - Index out range even If I made concurrent checking using when-else

I'm implementing a register file where I wanna read asynchronously and write on the rising edge.
I made concurrent checks on the addresses and the writing occurs inside a process.
However, it always cause me a fatal error and I don't know why!
Here's my code if anyone could help and tell me how can I read asynchronously and write on rising edge
Thank you!
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity RegFile is
port(
outData1 : out std_logic_vector(15 downto 0);
outData2 : out std_logic_vector(15 downto 0);
inData : in std_logic_vector(15 downto 0);
writeEn : in std_logic;
reg1Sel : in std_logic_vector(2 downto 0);
reg2Sel : in std_logic_vector(2 downto 0);
writeRegSel : in std_logic_vector(2 downto 0);
clk : in std_logic
);
end RegFile;
architecture Register_File of RegFile is
type registerFile is array(0 to 5) of std_logic_vector(15 downto 0);
signal registers : registerFile;
signal reg1Address,reg2Address : integer;
signal reg1FinalAddressing,reg2FinalAddressing : std_logic_vector(2 downto 0);
begin
--Conversion of logic vector to unsigned integer
reg1Address <= to_integer(unsigned(reg1Sel));
reg2Address <= to_integer(unsigned(reg2Sel));
reg1FinalAddressing <= reg1Sel when (reg1Address<6 ) else
(others => '0');
reg2FinalAddressing <= reg2Sel when (reg2Address<6 ) else
(others => '0');
outData1 <= registers(to_integer(unsigned(reg1FinalAddressing)));
outData2 <= registers(to_integer(unsigned(reg2FinalAddressing)));
process (clk) is
begin
-- Reading from Registers 1 and 2
if rising_edge(clk) then
-- Writing to Register file Case Enabled
if writeEn = '1' then
registers(to_integer(unsigned(writeRegSel))) <= inData;
-- Case a value being written to register file, it will be out simultaneously if
-- the register was already selected. (The updated values are being released instantly).
if reg1Sel = writeRegSel then
outData1 <= inData;
end if;
if reg2Sel = writeRegSel then
outData2 <= inData;
end if;
end if;
end if;
end process;
end Register_File;

= can not have such operands in this context

Here's the full error: ERROR:HDLParsers:808 - "C:/Users/vROG/Desktop/.../CacheController.vhd" Line 72. = can not have such operands in this context.
I'd understand how to fix this if I was used '+' or '*', but equal sign?
As you can tell, the code isn't nearly being close to completely, but I can't understand why my second nested if isn't working. I've tried turning dirtyBIT to type int, but it still gives me the same error, which leads me to believe that I made a trivial error somewhere.
FIXED (Using user1155120's advice) However how do I resolve the issue with offset and tag?
architecture Behavioral of CacheController is
signal tagFROMCPU : STD_LOGIC_VECTOR(7 downto 0) := CPU_addr(15 downto 8);
signal indexFROMCPU: STD_LOGIC_VECTOR(2 downto 0) := CPU_addr(7 downto 5);
signal offsetFROMCPU: STD_LOGIC_VECTOR(4 downto 0) := CPU_addr(4 downto 0);
TYPE STATETYPE IS (state_0, state_1, state_2, state_3);
SIGNAL present_state : STATETYPE;
--Variables
signal dirtyBIT: std_logic_vector (7 downto 0);
signal validBIT: std_logic_vector (7 downto 0);
TYPE tag is array (7 downto 0) of STD_LOGIC_VECTOR(7 downto 0);
TYPE offset is array (7 downto 0) of STD_LOGIC_VECTOR(4 downto 0);
signal myTag: tag;
signal myOFFSET : offset;
begin
--STATE MACHINE
process(clk)
begin
if (present_state = state_0) then --Start State : Checks for HIT or MISS, PERFORMS HIT OPERATION or MOVES TO STATE_1
if ((myTag(to_integer(unsigned(indexFROMCPU)) = tagFROMCPU)) then
--HIT
else
present_state <= state_1;
end if;
elsIF (present_state = state_1) then --CHECKS DIRTY BIT. IF 0, LOADS DATA, MOVES TO STATE_0 ELSE move to state_2
if (dirtyBit(to_integer(unsigned(indexFROMCPU))) = '0') then
present_state <= state_0;
else
present_state <= state_2;
end if;
elsIF(present_state = state_2) then -- DIRTY BIT IS 1, SAVES DATA, goes back to STATE_1
present_state <= state_1;
end if;
end process;
end Behavioral;
OLD CODE
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity CacheController is
Port (
clk : in STD_LOGIC;
CPU_addr : in STD_LOGIC_VECTOR (15 downto 0);
CPU_WR_RD : in STD_LOGIC;
CPU_CS : in STD_LOGIC;
CPU_RDY : out STD_LOGIC;
SDRAM_Addr : out STD_LOGIC_VECTOR (15 downto 0);
SDRAM_WR_RD : out STD_LOGIC;
SDRAM_MSTRB : out STD_LOGIC;
MUX1,MUX2 : out STD_LOGIC;
SRAM_Addr : out STD_LOGIC_VECTOR (7 downto 0);
SRAM_WEN : out STD_LOGIC
);
end CacheController;
architecture Behavioral of CacheController is
signal tagFROMCPU : STD_LOGIC_VECTOR(7 downto 0) := CPU_addr(15 downto 8);
signal indexFROMCPU: STD_LOGIC_VECTOR(2 downto 0) := CPU_addr(7 downto 5);
signal offsetFROMCPU: STD_LOGIC_VECTOR(4 downto 0) := CPU_addr(4 downto 0);
TYPE STATETYPE IS (state_0, state_1, state_2, state_3);
SIGNAL present_state : STATETYPE;
--Variables to emulate SRAM
TYPE dirtyBIT is array (7 downto 0) of std_logic;
TYPE validBIT is array (7 downto 0) of std_logic;
TYPE tag is array (7 downto 0,7 downto 0) of std_logic;
TYPE offset is array (7 downto 0,4 downto 0) of std_logic;
begin
--STATE MACHINE
process(clk)
begin
if (present_state = state_0) then --Start State : Checks for HIT or MISS, PERFORMS HIT OPERATION or MOVES TO STATE_1
elsIF (present_state = state_1) then --CHECKS DIRTY BIT. IF 0, LOADS DATA, MOVES TO STATE_0 ELSE move to state_2
if (dirtyBit(to_integer(unsigned(indexFROMCPU))) = '0') then
present_state <= state_0;
else
present_state <= state_2;
end if;
elsIF(present_state = state_2) then -- DIRTY BIT IS 1, SAVES DATA, goes back to STATE_1
present_state <= state_1;
end if;
end process;
end Behavioral;
Operator overload resolution (for the "=" operator) requires a function be declared with a matching signature (types of the left and right inputs and the return type).
if (dirtyBit(to_integer(unsigned(indexFROMCPU))) = '0') then
Change the declaration for dirtyBit:
--Variables to emulate SRAM
-- TYPE dirtyBIT is array (7 downto 0) of std_logic;
signal dirtyBIT: std_logic_vector (7 downto 0);
And your code analyzes. I'd suggest the other type declaration (validBIT, tag and offset) should be similarly treated.
It looks like there should be an array type where offset is used. The type name might be changed to preserve offset as a signal name.

Unable to split a Vector in VHDL

I am unable to update reg_1 and reg_2 vectors by splitting reg_mem?
This is my code in VHDL which i had written in MODELSIM:
In other program i tried to split another vector into two parts and store them into two different Vectors.It worked fine.But same syntax is not working in this code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Register_unit is
port (
reg_read : in std_logic;
reg_write : in std_logic;
reg_mem : inout std_logic_vector(3 downto 0);
reg_start : inout std_logic_vector(3 downto 0);
reg_end : inout std_logic_vector(3 downto 0);
reg_write_comp : out std_logic;
reg_read_comp : out std_logic;
reg_1 : inout std_logic_vector(1 downto 0);
reg_2 : inout std_logic_vector(1 downto 0));
end Register_unit;
architecture Register_unit_arch of Register_unit is
begin
process (reg_read,reg_write)
begin
if (reg_read = '1' and reg_write = '0') then
reg_end <= reg_mem;
reg_read_comp <= '1';
elsif (reg_write = '1' and reg_read = '0') then
reg_mem <= reg_start;
reg_write_comp <= '1';
end if;
reg_1 <= reg_mem(1 downto 0); --reg_1 is not getting updated
reg_2 <= reg_mem(3 downto 2); --reg2 is not getting updated
end process;
end Register_unit_arch;
reg_1 and reg_2 is updated but they are updated to previous value of the reg_mem. This line;
reg_mem <= reg_start;
is not in effect until the end of process. You are making the reg_1 and reg_2 assignment before reg_mem has it's new value!
VHDL doesn't work top down like a programming language even if you are in a process.
In your case you should either use a variable (*) or directly assign from reg_start like this;
reg_1 <= reg_start(1 downto 0);
reg_2 <= reg_start(3 downto 2);
(*) variables are immediately assigned in a process, you can use them similar to programming language variables

VHDL : Value not propagating to port map

I have the below VHDL file, where i am facing problem. The final sum is getting the value undefined always.
CL_Adder is the Carry lookahead adder and is check as individual component and is working fine. Regstr module is also working fine.
The problem is with the reslt, reslt_out1, reslt_out2 variables usage ..!
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.CS_Adder_Package.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 movingaverage is
Port ( sin : in STD_LOGIC_VECTOR (10 downto 0);
clk : in STD_LOGIC;
rst : in STD_LOGIC;
--reslt_in: in std_logic_vector(14 downto 0);
sout : out STD_LOGIC_VECTOR (10 downto 0)
--reslt_out: out std_logic_vector(14 downto 0)
);
end movingaverage;
architecture Structural of movingaverage is
component Regstr is
port ( d : in STD_LOGIC_VECTOR (10 downto 0);
clk : in STD_LOGIC;
rst : in STD_LOGIC;
q : out STD_LOGIC_VECTOR (10 downto 0));
end component;
component CL_Adder is
Port ( x : in STD_LOGIC_VECTOR (14 downto 0);
y : in STD_LOGIC_VECTOR (14 downto 0);
cin : in STD_LOGIC;
s : out STD_LOGIC_VECTOR (14 downto 0);
cout : out STD_LOGIC);
end component;
signal s: input_array;
signal s_se :std_logic_vector(14 downto 0):= (others =>'0');
signal s_se1 :std_logic_vector(14 downto 0):= (others =>'0');
signal s_se2 : std_logic_vector(14 downto 0):= (others =>'0');
signal reslt : std_logic_vector(14 downto 0):= (others =>'0');
signal reslt_out1: std_logic_vector(14 downto 0):= (others =>'0');
signal reslt_out2: std_logic_vector(14 downto 0):= (others =>'0');
signal c1,c2: std_logic;
begin
u0: for i in 15 downto 1 generate
u1:regstr port map(s(i-1)(10 downto 0),clk,rst,s(i)(10 downto 0));
end generate u0;
u7:regstr port map(sin,clk,rst,s(0)(10 downto 0));
s_se(14 downto 0) <= sin(10) & sin(10) & sin(10) & sin(10) & sin(10 downto 0);
reslt<= reslt_out2;
u8:CL_Adder port map(s_se,reslt,'0',reslt_out1,c1);
s_se1<= s(15)(10) & s(15)(10) & s(15)(10) & s(15)(10) & s(15)(10 downto 0);
s_se2 <= not(s_se1);
u9:CL_Adder port map(reslt_out1,s_se2,'1',reslt_out2,c2);
Sout <= reslt(14 downto 4); --divide by 16
end Structural;
Without more code I must add a little guessing, but could look like there is a
loop in the design in reslt => reslt_out1 => reslt_out2 => reslt, since
there is no clock (clk) on CL_Adder in the code:
reslt <= reslt_out2;
...
u8:CL_Adder port map(s_se, reslt, '0', reslt_out1, c1);
...
u9:CL_Adder port map(reslt_out1, s_se2, '1', reslt_out2, c2);
Whether this is the reason for the problem depends on how you see the
"undefined". In simulation the loop itself should not result in X (unknown),
or similar, but the loop hints a problem. Btw, you mention "variables usage",
but there are no variables in the shown code; only signals.
Addition:
If the purpose is to accumulate the value, then a sequential process (clocked process to make flip flops) may be used to capture the result of each iteration, and present as argument in next iteration. The reslt <= reslt_out2; may then be replaced with a process like:
process (clk, rst) is
begin
if rst = '1' then -- Reset if required
reslt <= (others => '0');
elsif rising_edge(clk) then -- Clock
reslt <= reslt_out2;
end if;
end process;

Resources