- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello everyone,
I am trying to write some code to use the debounced keys on the Altera DE2 board. I have spent days on the same error: "Error (10820): Netlist error at lab1.vhd(49): can't infer register for CurAddr[0] because its behavior depends on the edges of multiple distinct clocks"process(clock, resetn)
variable CurAddr : std_logic_vector(3 downto 0);
variable CurData : std_logic_vector(7 downto 0);
variable output : std_logic_vector(6 downto 0);
begin
if(clock'EVENT and clock='1') then
if(key(3)'EVENT and key(3)='0') then
if(conv_integer(CurAddr) = 16) then
CurAddr := "0000";
end if;
CurAddr := CurAddr + "0001";
elsif(key(2)'EVENT and key(2)='0') then
if(conv_integer(CurAddr) = 0) then
CurAddr := "1111";
end if;
CurAddr := CurAddr - "0001";
elsif(key(1)'EVENT and key(1)='0') then
if(CurData = "11111111") then
CurData := "00000000";
end if;
CurData := CurData + 1;
elsif(key(0)'EVENT and key(0)='0') then
if(CurData = "00000000") then
CurData := "11111111";
end if;
CurData := CurData + 1;
end if;
end if;
ram_addr <= CurAddr; --STORE RAM_ADDR
data_in <= CurData; -- STORE DATA
hex6 <= led_out1; -- OUTPUT LED CODE
end process;
I have tried removing the key(#)'EVENT parts. This removes the error but then the Seven Segment Display increments randomly it seems. I am using the 4 keys on the DE2 to control a RAM address and increment or decrement the value in that address. 2 keys to increment/decrement the address and 2 to control the value. I have also tried chaning the variables to signals. This didn't help either. I have also tried changing it to process(key) and removing the 'EVENT part as well as changing key(3)'EVENT to key(3)'last_value='1'. I am having no luck or intelligence. Any suggestions? Thank you. V/R, Alan
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are right, you need the tick-event. That line means the clock has changed and it is nowt a '1'. Without the 'event, it just means when the clock is high, update this process, more like a transparent latch.
Take those signal assignments at the end and move them up just enough to be inside the clock edge if statement. This will make them rising edge registers.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Before experimenting with the VHDL trying to fix it by trial and error:
For logic, think about what you want the hardware to look like in terms of registers versus combinational logic. For the register portion, you will have a D input, clock, asynchronous reset, and possibly other inputs like a clock enable. Write your VHDL in the recommended coding style for registers that have those input signals. For the coding styles, see the Quartus handbook, Volume 1, Section II, Chapter 6. In that chapter, see "Coding Guidelines for Registers and Latches". For memory, go through a similar process to be clear about what you want for memory control signals like the clock. See "Inferring Memory Functions from HDL Code" in the same handbook chapter.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Good referrences, and this gives me the forum to push my favorite book for people settling on a coding approach, HDL Chip Design by Doug Smith. He has, for example, all the typical flavors of a Flip Flop written with example code "The way it should be done" for both verilog and VHDL. There are little dialog boxes pointing to and explaining how each variation in the HDL text gives you a slightly different feature. It's not deep, but if you are looking for the right approach to basic synthesizable code, this is the ticket.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the help. Pushing the signal assignments inside the if(clock'EVENT and clock='1') statement still generated the same error? I will read those links as well.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Get rid of the key(3)'EVENT and just use the value of key, as that will get rid of the error. You clk'EVENT already describes the clock for a register, and you can only have one clock for each register. Doug Smith's book should give you some good direction, although opening almost any VHDL file will show you the standard method for doing flops(Doug Smith's book will clarify what is going on). I think I mentioned this before, but I really think understanding schematics is a good way to start coding, even if you're writing VHDL/Verilog. If you're just starting coding, and can't imagine what the code you're writing would look like as a schematic, than you're in trouble. (The original code with multiple 'EVENT lines is a good example, is I don't know how to "draw" that.)
The second thing I would stay away from in VHDL is variables, and try to always use Signals. Signals represent physical nets in the design, and again would map to something in a schematic. I had a long argument with someone who loved Variables about this. He spent a lot of time trying to come up with logic where Variables did a better job than Signals. On all but one, I was able to do the same thing, in a more concise manner, with Signals. But the point is that if you're new to VHDL, it will keep you writing code that physically makes sense, rather than writing algorithms where you have no idea how they get synthesized and what comes out the other side. Finally, for your design, the fix I mentioned will get it to compile, but probably won't be what you want. If your level-sensitive to key, then if the user holds down the key for more than one clock cycle(and I'd like to meet the person who doesn't do that), then the pointers will keep iterating for many clocks. There are many ways to fix this, depending on how much caution you want to build in. Most likely you want a separate process for each key that is based on key'EVENT, where the register gets the inversion of itself(i.e. a toggle register where key(#) is the clock). THen you need to move that signal into your main clk domain, so have the output of that register feed two registers clocked by clk'EVENT. Take the output of those two registers and feed them into an XOR gate, which will go high whenever the two registers are not equal(i.e. an edge detect). That should be a good starting point. It may not be full-proof enough if your pushbuttons are launch warheads(I don't think we've gotten into metastability, correlation between multiple keys, etc.) but if the failure rate is one out of every trillion key strokes, I'm guessing that's fine for now.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for everyone's help. I didn't really understand most of it, but I'll check out those references. Here is the way I finally solved the problem:
if(clock'EVENT and clock='1') then
we <= '0';
if(key(3)='1' and key(2)='1' and key(1)='1' and key(0)='1') then
EnableKeyPress := '1';
end if;
if(key(3)='0' and EnableKeyPress='1') then
EnableKeyPress := '0';
if(conv_integer(ram_addr) = 16) then
ram_addr <= "0000";
else
ram_addr <= ram_addr + "0001";
end if;
elsif(key(2)='0' and EnableKeyPress='1') then
EnableKeyPress := '0';
if(conv_integer(ram_addr) = 0) then
ram_addr <= "1111";
else
ram_addr <= ram_addr - "0001";
end if;
elsif(key(1)='0' and EnableKeyPress='1') then
EnableKeyPress := '0';
we <= '1';
if(data_out = "11111111") then
data_in <= "00000000";
else
data_in <= data_in + 1;
end if;
elsif(key(0)='0' and EnableKeyPress='1') then
EnableKeyPress := '0';
we <= '1';
if(data_out = "00000000") then
data_in <= "11111111";
else
data_in <= data_in - 1;
end if;
end if;
end if;
It seems to work. I have a few quarks to work out with the ram, but the button detecting code works. Thanks for all the help. Does anyone see any reason why this code should not be used?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I suggested thinking in terms of how you want your logic implemented in physical resources like registers and register control signals. Then Rysc suggested doing that by thinking about how the logic looks in a schematic. Now that you have something you can synthesize, you can look at a post-synthesis schematic that represents what you did do. By comparing post-synthesis schematics to your HDL, you can see how the HDL was translated to physical device resources. This might help you next time to think in advance about how you want your logic to look as a schematic so that you can write the HDL in a style that produces what you want in hardware.
To see a direct correspondence between the HDL and an equivalent schematic representation of the logic as generic registers, muxes, AND gates, etc., use the RTL Viewer. To see the next step of how that logic maps into the device's registers, LUTs, RAM blocks, etc, use the Technology Map Viewer. Both of these schematic viewers are available at Tools --> Netlist Viewers. Documentation on the schematic viewers is in the Quartus handbook, Volume 1, Section III, Chapter 12: Analyzing Designs with Quartus II Netlist Viewers.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you. I will check out those references in the lab today after lunch.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"I didn't really understand most of it, but I'll check out those references."
In general, I find that if you do not really understand how something is supposed to work, it is next to impossible to get what you want. Check out the references cited, and take the time to really get it. You will be very happy you spent the time up front 'for the rest of your life'.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I received the same error about the multiple clocks. My design had the following format:
process (rst, clk) begin
if rising_edge(rst) then
-- asynchronous reset stuff
elsif rising_edge(clk) then
-- synchronous stuff
end if;
end process;
The fix for me was to change my reset from rising edge triggered to level sensitive: process (rst, clk) begin
if (rst = '1') then
-- asynchronous reset stuff
elsif rising_edge(clk) then
-- synchronous stuff
end if;
end process;
Hope this helps.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have the similar error when I try to compile a code to stretch an input pulse for some clock cycles .
The code compiles and simulates perfectly,except when I add the line "shp_out<=shaped_output"..where I tryto put the signal shaped_output into the port shp_out. It gives me an Error (10820):: can't infer register because its behavior depends on the edges of multiple distinct clocks entity integrate1 is port ( trig : out std_logic; trigger_input,clk_pulse: inout STD_LOGIC ); end integrate1; architecture arc of integrate1 is signal shaped_output: std_logic:='0'; signal tmp: std_logic_vector(10 downto 0); signal shp_out:std_logic; begin process (clk_pulse,trigger_input) begin if (rising_edge(trigger_input)) then tmp<="00000000000"; shaped_output<='1'; end if; if shaped_output='1' then if (tmp="00000000100") then tmp <= "00000000000"; shaped_output<='0'; elsif (clk_pulse'event and clk_pulse='1') then tmp <= tmp + 1; end if; end if; end process; shp_out<=shaped_output;<<<<<<<<<<----------PROBLEM end arc;- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Don't use two clocks in the same process. Just read and act on the trigger input inside the "elsif (clk_pulse'event and clk_pulse='1')" part of the process.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page