Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
1,249 Views

Trying to generate a signal.

Hello :) 

 

I am really new with VHDL, I am doing my thesis coding in it, and I am stuck in some parts, so maybe someone could help me? 

 

I have created an optimized 4x4 bits multiplier, and i need to extract the results from that. I mean: 

 

A3A2A1A0 X B3B2B1B0 = C3C2C1C0 D3D2D1D0  

0000 x 0001 = 0000 0000 

1010 x 1010 = 0010 1010 

 

So, I am trying to create signals from 0 0 to 9 9 for my multiplier in wthis way: 

 

 

--- Quote Start ---  

library std; 

LIBRARY ieee; 

use std.textio.all;  

USE ieee.std_logic_1164.all;  

 

entity TBMULT is 

port(a3,a2,a1,a0,b3,b2,b1,b0 : OUT STD_LOGIC); 

end TBMULT; 

 

architecture Behavioral of TBMULT is 

 

signal first, second : std_LOGIC_VECTOR (3 downto 0); 

signal clock : bit := '0'; 

 

 

begin 

 

clock <= not (clock) after 0.5 ns;  

 

process (clock) 

begin 

for i in 0 to 9 loop 

for j in 0 to 9 loop 

CASE I IS 

when 0 => first <= "0000"; 

when 1 => first <= "0001"; 

when 2 => first <= "0010"; 

when 3 => first <= "0011"; 

when 4 => first <= "0100"; 

when 5 => first <= "0101"; 

when 6 => first <= "0110"; 

when 7 => first <= "0111"; 

when 8 => first <= "1000"; 

when others => first <= "1001"; 

end case; 

 

CASE J IS 

when 0 => second <= "0000"; 

when 1 => second <= "0001"; 

when 2 => second <= "0010"; 

when 3 => second <= "0011"; 

when 4 => second <= "0100"; 

when 5 => second <= "0101"; 

when 6 => second <= "0110"; 

when 7 => second <= "0111"; 

when 8 => second <= "1000"; 

when others => second <= "1001"; 

end case; 

 

a3 <= first(3); 

a2 <= first(2); 

a1 <= first(1); 

a0 <= first(0); 

 

b3 <= second(3); 

b2 <= second(2); 

b1 <= second(1); 

b0 <= second(0); 

 

end loop; 

end loop; 

end process; 

 

 

end Behavioral; 

--- Quote End ---  

 

 

I wire it to my multiplier in this way:  

 

https://alteraforum.com/forum/attachment.php?attachmentid=14522&stc=1  

 

But when i simulate it, i only get 1000 0001 (81) the result from 9*9, and I was specting all the multiplications. 

 

Any hints?
0 Kudos
6 Replies
Altera_Forum
Honored Contributor I
53 Views

Thats because the loop that occurs on the clock edges (and it will be both falling and rising edge, because you didnt put an edge condition in there) completes on every loop. Because signals only take the last thing assigned to them, they take the last assignment, which is 9. 

 

You need a wait in the loop so that it increments on every clock. Something like this: 

 

use ieee.numeric_std.all; process -- note - no sensitivity list variable first, second : unsigned(3 downto 0); begin for i in 0 to 9 loop second := to_unsigned(i, 4); b3 <= second(3); b2 <= second(2); b1 <= second(1); b0 <= second(0); for j in 0 to 9 loop first := to_unsigned(j, 4); a3 <= first(3); a2 <= first(2); a1 <= first(1); a0 <= first(0); wait until rising_edge(clk); end loop; end loop; wait; end process;
Altera_Forum
Honored Contributor I
53 Views

Tricky's answer is certainly the most elegant way to do exactly what you asked.  

 

If you wanted to test all possibilities, another way would be to use an unsigned 8-bit signal and just increment it by one each clock cycle. first is the upper 4-bits and second is the lower 4-bits. You could even get rid of first and second and just write: 

 

signal counter : unsigned(7 downto 0) := (others => '0'); process begin wait until CLK'EVENT and CLK = '1'; counter <= counter + 1; a3 <= counter(7); a2 <= counter(6); ... b3 <= counter(3); ... b0 <= counter(0); end process;  

 

If your operands were larger, say 32-bits, you could increment by a value > 1 to limit the number of tests.  

 

If you're allowed to make a and b arrays (maybe call them first and second), it would get even simpler and then easily scales to other size operands.
Altera_Forum
Honored Contributor I
53 Views

Thanks a lot for you answers! Unfortunately, they did not worked for me. I have the following problems: 

 

 

--- Quote Start ---  

Tricky's answer is certainly the most elegant way to do exactly what you asked.  

 

If you wanted to test all possibilities, another way would be to use an unsigned 8-bit signal and just increment it by one each clock cycle. first is the upper 4-bits and second is the lower 4-bits. You could even get rid of first and second and just write: 

 

signal counter : unsigned(7 downto 0) := (others => '0'); process begin wait for rising_edge(clk); counter <= counter + 1; a3 <= counter(7); a2 <= counter(6); ... b3 <= counter(3); ... b0 <= counter(0); end process;  

 

If you're allowed to make a and b arrays (maybe call them first and second), it would get even simpler and then easily scales to other size operands. 

--- Quote End ---  

 

 

Instead of the loops, I have copied this, but then an error shows up: 

 

"rising_edge type specified in Qualified Expression must match time type that is implied for expression by context" 

 

And I don't exactly know how to solve it, I have googled it but no one of the answers worked :( 

 

 

--- Quote Start ---  

Thats because the loop that occurs on the clock edges (and it will be both falling and rising edge, because you didnt put an edge condition in there) completes on every loop. Because signals only take the last thing assigned to them, they take the last assignment, which is 9. 

 

You need a wait in the loop so that it increments on every clock. Something like this: 

 

use ieee.numeric_std.all; process -- note - no sensitivity list variable first, second : unsigned(3 downto 0); begin for i in 0 to 9 loop second := to_unsigned(i, 4); b3 <= second(3); b2 <= second(2); b1 <= second(1); b0 <= second(0); for j in 0 to 9 loop first := to_unsigned(j, 4); a3 <= first(3); a2 <= first(2); a1 <= first(1); a0 <= first(0); wait until rising_edge(clk); end loop; end loop; wait; end process;  

--- Quote End ---  

 

 

I tyied this one as well, and the problem is: 

 

"Process statement must contain only one wait statement" 

 

It works if I take it out of the loops, but the result is the same, in the simulation it only works with 9*9 

 

 

I find the clock really logic, I mean, I realized that for sure I need one, but I still not knowing how to use it. Anyway I think I am closer to the answer :)
Altera_Forum
Honored Contributor I
53 Views

 

--- Quote Start ---  

"rising_edge type specified in Qualified Expression must match time type that is implied for expression by context" 

--- Quote End ---  

 

 

That is because you (and corestar) used "wait for". wait for expects a time expression, while rising_edge(clk) is a boolean expression based on a signal transition. You need to use "wait until", like in my example. 

 

 

--- Quote Start ---  

"Process statement must contain only one wait statement" 

--- Quote End ---  

 

 

Thats because you have tried to compile the code in Quartus - the quartus simulator will only simulate synthesisable code, and my code was definitely not synthesisable, only for testbenches. You need to run it in an RTL simulator, like modeslim.
Altera_Forum
Honored Contributor I
53 Views

Sorry about that. I did not actually compile it; I just quickly typed some code as a rough example. I normally use "wait until CLK'EVENT and CLK = '1'" and edited it accordingly. Using "wait until rising_edge(clk)" should work as well.  

 

You did not say if this was for simulation or synthesis. Synthesis will not allow multiple wait statements but Modelsim simulation will (as per Tricky's example).
Altera_Forum
Honored Contributor I
53 Views

I just solved it and the code works perfectly! Thank you for everything, it was really usefull :)!!

Reply