Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Problem with VHDL Code Modification

Status
Not open for further replies.

salim.alam2

Junior Member level 3
Joined
May 8, 2016
Messages
27
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
246
Hi

I hope you are doing well

Actually, I am beginner in VHDL and FPGA, and I will be grateful to you if you can help me.

I have a code in VHDL and I should:

a. Modify the VHDL code of the calculator circuit:
(i) To include a flip operation that complements all bits in dReg.
(ii) To detect arithmetic error conditions. An unsigned addition results in an
arithmetic error if it produces a sum that is too large to fit in the register
used by the calculator (note that the calculator uses a 16 bit register).
Whenever an error is detected, the calculator should set an internal error
bit. The error bit should be cleared when a clear operation is performed
and no other operations should be allowed to occur while the error bit is
set.

for the following code:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Library IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;[CODE][/CODE]
Entity calculator is
Port ( clk : in std_logic; -- clock
 Clear, load, add : in std_logic; -- operation signals
 Din : in std_logic_vector (15 downto 0); -- input data
 Result : out std_logic_vector (15 downto 0)); -- output data
End calculator
Architecture a1 of calculator is
Signal dReg : std_logic_vector (15 downto 0);
Begin
Process (clk)
Begin
 If rising_edge (clk) then
 If clear =1then
 dReg <= ”0000000000000000”;
 elsif load=1then
 dReg <= din;
 elsif add=1then
 dReg <= std_logic_vector(unsigned(dreg) + unsigned(din));
--values of dreg and din are converted to unsigned type with unsigned() function.
--the unsigned values are added
--the result is converted to standard logic vector with std_logic_vector() function.
 
 end if;
 end if;
en process;
result <= dreg;
end a1;

 
Last edited by a moderator:

What help do you need?

As you have not asked a question it is impossible to determine what you need help with, but don't expect someone to write the code for you.
 

What help do you need?

As you have not asked a question it is impossible to determine what you need help with, but don't expect someone to write the code for you.

My question is how to modify the code to include a flip operation that complements all bits in dReg, and how to modify the code to detect arithmetic error conditions. An unsigned addition results in an arithmetic error if it produces a sum that is too large to fit in the register used by the calculator (note that the calculator uses a 16 bit register).Whenever an error is detected, the calculator should set an internal error bit. The error bit should be cleared when a clear operation is performed and no other operations should be allowed to occur while the error bit is set.
 

That is the assignment problem statement, which you are supposed to know how to solve from what has been taught in class. If you have a specific problem then show us the code that you've written as the solution to your assignment and we can help you get it working, but we aren't going to write your assignment for you or give you an "example" that exactly implements your assignment.

Did you even look at the code you posted and how it selects different functions based on the input signals: clear, load, and add? To add the complement function add another elsif with an input to select that function.
 
Actually, it is an assignment and I was working on it, and i want to make sure that I am on the right way.

because it is so important to me and i am interested in VHDL and FPGA, this code has a lot of errors and i fixed it.

Thank you for your help ;-)
 

Thanks for the previous help

I think I made a mistake because I did not attached a photo for the circuit, I am sorry for that.

Untitled.jpg

I was thinking that complement of the D-flip flop is Q' ??is that's correct?

so what is have to do is to add an extra output to the circuit and call it Q', and this Q' should be [NOT Q]??

And this a copy of my code after some corrections

Code:
Library IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;

Entity calculator is
Port ( clk : in std_logic; 				 -- clock
	Clear, load, add : in std_logic;		 -- operation signals
 	Din : in std_logic_vector (15 downto 0);	 -- input data
	Result : out std_logic_vector (15 downto 0));	 -- output data
End calculator;

Architecture a1 of calculator is
Signal dReg : std_logic_vector (15 downto 0);
Begin
Process (clk)
Begin
	If (rising_edge (clk)) then
 		If (clear ='1') then
 			dReg <= ”"0000000000000000";
		elsif (load='1') then
 			dReg <= Din;
 		elsif (add='1') then
 			dReg <= std_logic_vector(unsigned(dReg) + unsigned(Din));

			--values of dreg and din are converted to unsigned type with unsigned() function.
			--the unsigned values are added
			--the result is converted to standard logic vector with std_logic_vector() function.

		end if;
 	end if;
end Process;
Result <= dReg;
end a1;

I tried to compile it with ModelSim, but i got an error with the line [dReg <= ”"0000000000000000";], it says :
near "<byte 0x94>": illegal character found in source

Thanks in advanced for your help.


This is a screenshot
Untitled.png
 

Which is the code you compiled? The code in the picture for line 20 has no issue (unless there is an undisplayed character). The copied code has an extra character before the first double quote. If that code is the correct code then Quartus probably can't display the extra character before the quoted string.
 
It doesn't sound like you need a Q' output. The description indicates you need to do the following:
1.) add a "negate" input. it seems assumed that clear, negate, add, and load will be mutually exclusive.
2.) add an error bit that occurs when when an addition overflows. This can be done by making the result of the addition 17b. Making dReg into a 17b value has some additional complications, as you need to avoid setting the msb to 1 in the negate operation.
3.) have a nested if statement based on the error bit, preventing add, negate, and load from working until clear is used. "error" does not appear to be an output, although that would make more sense.
 
I compiled the code in the screenshot, the problem exactly as you said Quartus was not able to display the extra character.
Thanks a lot

- - - Updated - - -

It doesn't sound like you need a Q' output. The description indicates you need to do the following:
1.) add a "negate" input. it seems assumed that clear, negate, add, and load will be mutually exclusive.
2.) add an error bit that occurs when when an addition overflows. This can be done by making the result of the addition 17b. Making dReg into a 17b value has some additional complications, as you need to avoid setting the msb to 1 in the negate operation.
3.) have a nested if statement based on the error bit, preventing add, negate, and load from working until clear is used. "error" does not appear to be an output, although that would make more sense.

I am so sorry but some points that i did not understand :-(
1. do you mean that i have to add an extra input? why? and "negate" means negative?
2. do you mean that i have to make the dReg <="00000000000000000"??
3. do you mean that i have to add if dReg <="1xxxxxxxxxxxxxxxx" then clear(Clear=1);?
Thanks for your help
 

ah, yeah I missed that. I guess the port name would be something like logicalNot, or whatever fits your naming scheme that isn't a reserved word.

There are a few ways to do the overflow condition. you could also check to see if (x+y < x), but I don't really like that as much because the construct can fail to work in some languages. IIRC, VHDL is safe as long as the size of x is equal or greater than the size of y.

Really, the addition should either be done outside of the clocked process, or in a variable. This is the cleaner way to do things. At first I figured this would be more difficult to explain and more error prone than making dReg 17b. I guess it isn't. Just make a 17b signal and assign it outside of the process for now. it would be ('0'&dReg) + din. Then the addition would assign dReg to be the lower 16b, and eReg (guessing that is what you would name it) to be the msb.
 
Hi
I made some changes on the code
Code:
Library IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;

Entity calculator is
Port ( clk : in std_logic; 				 -- clock
	Clear, load, add, complement : in std_logic;		 -- operation signals
 	Din : in std_logic_vector (15 downto 0);	 -- input data
	Result : out std_logic_vector (15 downto 0);	 -- output data
End calculator;

Architecture a1 of calculator is
Signal dReg : std_logic_vector (15 downto 0);
Begin
Process (clk)
Begin
	If (rising_edge (clk)) then
 		If (clear ='1') then
      dReg <= "0000000000000000";
		elsif (load='1') then
 			dReg <= Din;
 		elsif (add='1') then
 			dReg <= std_logic_vector('0'& unsigned(dReg)+ unsigned(Din)); -- Using '0'& to be able to assign additional bit
 			case (dReg) is 
 			  when "1****************" => load <= '0';
 			  when "1****************" => add <= '0';
 			  when "1****************" => complement <= '0';
 			end case;
 		elsif (complement='1') then
 			dReg <=  Din;

			--values of dreg and din are converted to unsigned type with unsigned() function.
			--the unsigned values are added
			--the result is converted to standard logic vector with std_logic_vector() function.

		end if;
 	end if;
end Process;
Result <= dReg;
end a1;

The point is when compiling i have an error : near "End": expecting FUNCTION or PROCEDURE or IMPURE or PURE

1.png

And i was trying to deactivate the ports by setting there value to 0, so is that's OK or wrong, if not is there is any command or any way to deactivate a specific ports in a specific cases?
 

Hi
I made some changes on the code
Code:
Entity calculator is
Port ( clk : in std_logic;                  -- clock
    Clear, load, add, complement : in std_logic;         -- operation signals
     Din : in std_logic_vector (15 downto 0);     -- input data
    Result : out std_logic_vector (15 downto 0);     -- output data
End calculator;
The point is when compiling i have an error : near "End": expecting FUNCTION or PROCEDURE or IMPURE or PURE
You missed the closing right parentheses at the end of the port list and there should be no terminating semi-colon at the end of the last entry in the port list. See below, changes in red font
Code:
Entity calculator is
Port ( clk : in std_logic;                  -- clock
    Clear, load, add, complement : in std_logic;         -- operation signals
     Din : in std_logic_vector (15 downto 0);     -- input data
    Result : out std_logic_vector (15 downto 0)[B][COLOR=#FF0000]);[/COLOR][/B]     -- output data
End calculator;

Kevin Jennings
 
Thanks a lot for your help

actually, what i am trying to do is to make the result of the sum is 17 bit, instead of 16 bit and when this last bit is '1', i want the circuit to stop working until performing clear again.

I made some changes
Code:
Library IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;

Entity calculator is
Port ( clk : in std_logic; 				                      -- clock
	Clear, load, add, complement : in std_logic;		     -- operation signals
 	Din : in std_logic_vector (15 downto 0);	          -- input data
 	Erorr : in bit := 0;                               -- the erorr bit
	Result : out std_logic_vector (15 downto 0));	     -- output data
End calculator;

Architecture a1 of calculator is
Signal dReg : std_logic_vector (15 downto 0);
Begin
Process (clk)
Begin
	If (rising_edge (clk)) then
 		If (clear ='1') then
      dReg <= "0000000000000000";
		elsif (load='1') then
 			dReg <= Din;
 		elsif (add='1') then
 			dReg <= std_logic_vector(Erorr & unsigned(dReg)+ unsigned(Din)); -- Using '0'& to be able to assign additional bit
 			case (Erorr) is 
 			  when '1' => Clear <= '1';
 			end case;
 		elsif (complement='1') then
 			dReg <= not Din;

			--values of dreg and din are converted to unsigned type with unsigned() function.
			--the unsigned values are added
			--the result is converted to standard logic vector with std_logic_vector() function.

		end if;
 	end if;
end Process;
Result <= dReg;
end a1;

any idea how to do that??
 

Thanks a lot for your help

actually, what i am trying to do is to make the result of the sum is 17 bit, instead of 16 bit and when this last bit is '1', i want the circuit to stop working until performing clear again.

I made some changes
Code:
Library IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;

Entity calculator is
Port ( clk : in std_logic; 				                      -- clock
	Clear, load, add, complement : in std_logic;		     -- operation signals
 	Din : in std_logic_vector (15 downto 0);	          -- input data
 	Erorr : in bit := 0;                               -- the erorr bit
	Result : out std_logic_vector (15 downto 0));	     -- output data
End calculator;

Architecture a1 of calculator is
Signal dReg : std_logic_vector (15 downto 0);
Begin
Process (clk)
Begin
	If (rising_edge (clk)) then
 		If (clear ='1') then
      dReg <= "0000000000000000";
		elsif (load='1') then
 			dReg <= Din;
 		elsif (add='1') then
 			dReg <= std_logic_vector(Erorr & unsigned(dReg)+ unsigned(Din)); -- Using '0'& to be able to assign additional bit
 			case (Erorr) is 
 			  when '1' => Clear <= '1';
 			end case;
 		elsif (complement='1') then
 			dReg <= not Din;

			--values of dreg and din are converted to unsigned type with unsigned() function.
			--the unsigned values are added
			--the result is converted to standard logic vector with std_logic_vector() function.

		end if;
 	end if;
end Process;
Result <= dReg;
end a1;

any idea how to do that??

Code:
process (clk) is
begin
  if rising_edge(clk) then
    if clear = '1' then
      -- dReg should be cleared
      -- any error flag should be cleared.
    elsif error_flag = '0' then
      if load = '1' then
        -- code for load
      elsif add = '1' then
        --code for the addition and to set the error_flag.  
      elsif complement = '1' then
        -- code for complement
      end if;
    end if;
  end if;
end process;


The key part here is creating the logic for "error_flag" as well as performing each operation. To help you out, I will mention that the following is incorrect:
Code:
process (clk) is
begin
  if rising_edge(clk) then
    x <= a + b;
    error_flag <= x(x'left); -- This adds +1 cycle of latency!
  end if;
end process;

There are two (or more...) options:
Code:
process (clk) is
begin
  if rising_edge(clk) then
    x <= a + b;
  end if;
end process;
error_flag <= x(x'left); -- placed outside of process.  can be annoying if process were long.

and

Code:
process (clk) is
  variable result : unsigned(16 downto 0); -- variables can be tricky as the assignements happen _within_ the process vs at the end of the process.
begin
  if rising_edge(clk) then
    result := a + b; -- happens at this line.
    x <= result(15 downto 0);
    error_flag <= result(16);
  end if;
end process;
 
Thank you for you help, that gave me some good ideas, I made some changes and I think that is correct? is it?

Code:
Library IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;

Entity calculator is
Port ( clk : in std_logic; 				                      -- clock
	Clear, load, add, complement : in std_logic;		      -- operation signals
 	Din : in std_logic_vector (15 downto 0);	                      -- input data
	Result : out std_logic_vector (15 downto 0));	              -- output data
End calculator;

Architecture a1 of calculator is
Signal dReg : std_logic_vector (15 downto 0);
Begin
Process (clk)
Begin
	If (rising_edge (clk)) then
 		If (clear ='1') then
      dReg <= "0000000000000000";
		elsif (load ='1') then
 			dReg <= Din;
 		elsif (add ='1') then
 			dReg <= std_logic_vector('0' & unsigned(dReg)+ unsigned(Din)); -- Using flag & to be able to assign additional bit
 			if (dReg(17) ='1') then  
 			  while (dReg(17)= '1') loop
 			    dReg(17) <= '0' + dReg(17);
 			  end loop;
 			 elsif (clear ='1') then
         dReg <= "0000000000000000"; 
 			end if;
 		elsif (complement='1') then
 			dReg <= not Din;

			--values of dreg and din are converted to unsigned type with unsigned() function.
			--the unsigned values are added
			--the result is converted to standard logic vector with std_logic_vector() function.

		end if;
 	end if;
end Process;
Result <= dReg;
end a1;

while compiling i got some problems like :

** Error: C:/.../Desktop/VHDL the last/VHDL-v2.vhdl(26): No feasible entries for infix operator "+".
** Error: C:/.../Desktop/VHDL the last/VHDL-v2.vhdl(26): Bad right hand side (infix expression) in signal assignment.
** Error: C:/.../Desktop/VHDL the last/VHDL-v2.vhdl(42): VHDL Compiler exiting.

2.png

Thanks in advance.
 

At least one error in the screenshot is more than clear its reason: The dReg signal is declared as being 16 bit size (15 downto 0), but you are attempting to access the 17th bit.
 
At least one error in the screenshot is more than clear its reason: The dReg signal is declared as being 16 bit size (15 downto 0), but you are attempting to access the 17th bit.

Thank you, I don't know how did i missed that, but i still have two problems :

** Error: C:/.../VHDL-v2.vhdl(26): No feasible entries for infix operator "+".
** Error: C:/.../VHDL-v2.vhdl(26): Bad right hand side (infix expression) in signal assignment.
3.png
 

thats because dreg(16) is a single bit, and there is not defined arithemtic functions for std_logic. You either need to make you own + function, do it with a 1 bit slice:

dreg(16 downto 16) <= "0" + dreg(16 dowto 16);

But whats the point? "0" plus a number is always just the number.
 

Thank you for you help, that gave me some good ideas, I made some changes and I think that is correct? is it?
Thanks in advance.

no, and in this case I'm having a hard time understanding the reasoning behind your changes.

You've added a while loop -- something that is exceptionally rare in synthesizable code. inside the while loop, you have dReg(17) -- a 1 bit scalar being assigned to '0' + dReg(17). This doesn't work for several reasons. First, dReg(17) doesn't exist as previously mentioned (it would also be the 18th bit). Second, "+" is not defined for two std_logic -- even in std_logic_unsigned this is not possible. Third, dReg <= '0' + dReg will only cause dReg to change at the end of the process -- this generates an infinite loop. Fourth, 0 + x = x, so even if the line were valid and took effect immediately, it wouldn't do anything.

In addition, you still don't have the nested if-else statements that I had suggested. (also you should attempt to post consistently indented code. It makes it easier on the reader.)
 

no, and in this case I'm having a hard time understanding the reasoning behind your changes.

You've added a while loop -- something that is exceptionally rare in synthesizable code. inside the while loop, you have dReg(17) -- a 1 bit scalar being assigned to '0' + dReg(17). This doesn't work for several reasons. First, dReg(17) doesn't exist as previously mentioned (it would also be the 18th bit). Second, "+" is not defined for two std_logic -- even in std_logic_unsigned this is not possible. Third, dReg <= '0' + dReg will only cause dReg to change at the end of the process -- this generates an infinite loop. Fourth, 0 + x = x, so even if the line were valid and took effect immediately, it wouldn't do anything.

In addition, you still don't have the nested if-else statements that I had suggested. (also you should attempt to post consistently indented code. It makes it easier on the reader.)

I am sorry of the miss understanding

1. I added the while loop because i want my system to stop working as long as i have the dReg (16) = '1'.
2. yes, you are right the "+" did not work for me, what do you suggest to use in this case?
3. by using dReg<='0'+dReg, i was trying to generate infinite loop to prevent the system from working unless performing 'clear' again.
4. I was thinking about using the 0+x=x, as a condition for the loop, so the system will stuck in this point until performing 'clear'.

I think i had the 'nested' but a called it 'complement' according to the request I got because what i was trying to do is:
1. To include a flip operation that complements all bits in dReg.
2. To detect arithmetic error conditions. An unsigned addition results in an arithmetic error if it produces a sum that is too large to fit in the register used by the calculator (note that the calculator uses a 16 bit register).
Whenever an error is detected, the calculator should set an internal error bit. The error bit should be cleared when a clear operation is performed and no other operations should be allowed to occur while the error bit is set.

and this is my code at the moment:

Code:
Library IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;

Entity calculator is
Port ( clk : in std_logic; 				                      -- clock
	Clear, load, add, complement : in std_logic;		     -- operation signals
 	Din : in std_logic_vector (15 downto 0);	          -- input data
	Result : out std_logic_vector (15 downto 0));	     -- output data
End calculator;

Architecture a1 of calculator is
Signal dReg : std_logic_vector (15 downto 0);
Begin
Process (clk)
Begin
	If (rising_edge (clk)) then
 		If (clear ='1') then
      dReg <= "0000000000000000";
		elsif (load ='1') then
 			dReg <= Din;
 		elsif (add ='1') then
 			dReg <= std_logic_vector('0' & unsigned(dReg)+ unsigned(Din)); -- Using flag & to be able to assign additional bit
 			if (dReg(16) ='1') then  
 			  while (dReg(16)= '1') loop
 			   dReg(16 downto 16) <= ("0" + dReg(16 downto 16));
 			  end loop;
 			 elsif (clear ='1') then
         dReg <= "0000000000000000"; 
 			end if;
 		elsif (complement='1') then
 			dReg <= not Din;

			--values of dreg and din are converted to unsigned type with unsigned() function.
			--the unsigned values are added
			--the result is converted to standard logic vector with std_logic_vector() function.

		end if;
 	end if;
end Process;
Result <= dReg;
end a1;

Thanks a lot for your help.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top