- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 :)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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).- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I just solved it and the code works perfectly! Thank you for everything, it was really usefull :)!!

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page