Community
cancel
Showing results for
Did you mean: 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?
Tags (1)
6 Replies 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; ``` 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. 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 :) 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. 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). Honored Contributor I
53 Views

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