- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I am working on a fairly simple VHDL design where I am trying to detect the rising_edge of an input. Whenever a rising_edge is detected I want to multiply another input by 2 and output it. The input that serves the "start" siginal is data_ready and it changes asynchronously. Since data_ready is not a clock it is my understanding that I cannot use rising_edge( data_ready ) so I store the previous value of data_ready. in an internal signal previous_value and compare it to the current value data_ready. It feel my code should work but during simulation it fails. What am I doing wrong?entity mul is port(
my_input : in std_logic_vector( 7 downto 0 );
data_ready : in std_logic;
my_output : out std_logic_vector( 8 downto 0 )
);
end mul;
architecture behavior of mul is
signal previous_value : std_logic := '0';
begin
mul_2 : process( data_ready )
begin
if data_ready = '1' AND previous_value = '0' then -- detect rising edge
previous_value <= data_ready; -- set previous value
my_output <= my_input( 7 downto 0 ) & "0"; -- mul by 2, shift left
else
my_output <= "111000111";
end if;
end process;
end behavior;
Testbench: BEGIN
-- code that executes only once
dataReady <= '0';
heading_in <= "11100011";
wait for 40ns;
dataReady <= '1'; -- generate rising edge
wait for 40ns; -- expected output 111000110
dataReady <= '0';
WAIT;
END PROCESS init;
Thanks for your help!
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your circuit design will not work in real hardware. Because you have no clock to time the registering of your signals, you're basically asking it to store the value of data_ready from 0s ago. Think about the circuit you expect and draw it on paper before writing the code.
FOr simulation, your code does work as you expected, assuming you're doing RTL simulation. If you're doing a netlist simulation (that you get with Quartus) then the problem will be because of what I said above. I suggest using a clock and synchronising your design. Memory elements are not really possible without one.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think what causes confusion to beginners is the term "edge detection".
We are used to think of "edge" as clock rising or falling edge. For other signals(apart from clock) we can't detect rising or falling edge but we want to identify the first transition pulse (that extends over one clock period). It is better defined as rising sample.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks both for your replies. I changed my code (see below) so it works on a rising_edge of a clock input and also removed the else statement since I got glitches on my_output. Seems like my_output was changed to quick. It works now
A follow up question to @Tricky comment: how do concurrent statements outside a process work then? Don't say also assume that the values are ready from 0s? e.g.my_output <= '111111111' when data_ready = '1';
Or would i use the after statement here? Changed code of the original question:(working now): entity mul is port(
clk : in std_logic;
my_input : in std_logic_vector( 7 downto 0 );
data_ready : in std_logic;
my_output : out std_logic_vector( 8 downto 0 )
);
end mul;
architecture behavior of mul is
signal previous_value : std_logic := '0';
begin
mul_2 : process( clk )
begin
if rising_edge( clk ) then
previous_value <= data_ready; -- set previous value
if data_ready = '1' AND previous_value = '0' then -- detect rising edge
my_output <= my_input(7 downto 0) & "0"; -- mul by 2, shift left
end if;
end if;
end process;
end behavior;
Testbench:
BEGIN
-- code that executes only once
data_ready <= '0';
my_input <= "11100011"; -- expected output 111000110
wait for 200ns;
data_ready <= '1';
wait for 200ns;
data_ready <= '0';
my_input <= "00110011";
wait for 200ns;
data_ready <= '1';
wait for 200ns;
WAIT;
END PROCESS init;
-- clock generation - 50MHz
process
begin
clk <= '1';
wait for 10 ns;
clk <= '0';
wait for 10 ns;
end process;
Cheers and thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- A follow up question to @Tricky comment: how do concurrent statements outside a process work then? Don't say also assume that the values are ready from 0s? e.g.
my_output <= '111111111' when data_ready = '1';
Or would i use the after statement here? --- Quote End --- They work exactly as you expect the underlying hardware to work. This example is fairly pointless - as it would set the output to all 1s when some data_ready input is '1', so you've built a latch because it does not have an else clause. The after keyword is purely for simulation. It has no meaning in a real circuit as absolute delay elements do not exist. They are meant to model the propogation delay that may occur in a real circuit. They will be removed for synthesis (with associated warnings). So unless you want them for modelling purposes, do not use them. If you have a synchronous design you will never need them.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- They work exactly as you expect the underlying hardware to work. This example is fairly pointless - as it would set the output to all 1s when some data_ready input is '1', so you've built a latch because it does not have an else clause. The after keyword is purely for simulation. It has no meaning in a real circuit as absolute delay elements do not exist. They are meant to model the propogation delay that may occur in a real circuit. They will be removed for synthesis (with associated warnings). So unless you want them for modelling purposes, do not use them. If you have a synchronous design you will never need them. --- Quote End --- Thanks for the clarification!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Unfortunately my earlier statement was wrong. I still see glitches with the synchronous code above. Here is the output from my test bench:
https://www.alteraforum.com/forum/attachment.php?attachmentid=13378 Is that normal?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Unfortunately my earlier statement was wrong. I still see glitches with the synchronous code above. Here is the output from my test bench: https://www.alteraforum.com/forum/attachment.php?attachmentid=13378 Is that normal? --- Quote End --- Well, now that I think about it. I guess it does not matter since my_output is stable at the next rising_edge. Before that my_output is not read by any other component.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Are you simulating the code or the post place and route netlist? This would be normal in the netlist as the tracks for each bit will be different lengths. As long as they dont violate the setup/hold times in timequest it will be ok.
This assumes that my_input and data_ready are synchronised to the clock domain. Using asynchronous signals will cause bad glitches. Note: in your testbench you are using absolute time delays - I recommend synchronising your testbench to your clock otherwise you might get delta problems if any input aligns with the clock.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't know whether it is the code or the post place & netlist. I am running a Gate Level Simulation. I am using Quartus II.
Thanks for your tip with the time delays!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I don't know whether it is the code or the post place & netlist. I am running a Gate Level Simulation. I am using Quartus II. Thanks for your tip with the time delays! --- Quote End --- Qate level simulation is the quartus compiled code you are simulating. You are not simulating your RTL directly.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page