I don't see a synchronizer on the rx data line.
All asynchronous inputs must be synchronized to the sampling clock. There are a couple of reasons for this: metastability and routing. These are different problems but are inter-related.
It takes time for signals to propagate through the FPGA fabric. The clock network inside the FPGA is designed to compensate for these "travel" delays so that all flip flops within the FPGA see the clock at the exact same moment. The normal routing network does not have this, and instead relies on the rule that all signals must be stable for a little bit of time before the clock changes and remain stable for a little bit of time after the clock changes. These little bits of time are known as the setup and hold times for a given flip flop. The place and route component of the toolchain has a very good understanding of the routing delays for the specific device and makes a basic assumption that a signal does not violate the setup and hold times of the flip flops in the FPGA. With that assumption and knowledge (and a timing constraints file) it can properly place the logic within the FPGA and ensure that all the logic that looks at a given signal sees the same value at every clock tick.
When you have signals that are not synchronized to the sampling clock you can end up in the situation where one flip flop sees the "old" value of a signal since the new value has not had time to propagate over. Now you're in the undesirable situation where logic looking at the same signal sees two different values. This can cause wrong operation, crashed state machines and all kinds of hard to diagnose havoc.
The other reason why you must synchronize all your input signals is something called metastability. There are volumes written on this subject but in a nutshell, digital logic circuitry is at its most basic level an analog circuit. When your clock line rises the state of the input line is captured and if that input is not a stable high or low level at that time, an unknown "in-between" value can be captured by the sampling flip flop.
As you know, FPGAs are digital beasts and do not react well to a signal that is neither high nor low. Worse, if that indeterminate value makes its way past the sampling flip flop and into the FPGA it can cause all kinds of weirdness as larger portions of the logic now see an indeterminate value and try to make sense of it.
The solution is to synchronize the signal. At its most basic level this means you use a chain of flip flops to capture the input. Any metastable level that might have been captured by the first flip flop and managed to make it out gets another chance to be resolved before it hits your complex logic. Two flip flops are usually more than sufficient to synchronize inputs.
A basic synchronizer looks like this:
entity sync_2ff is
port (
async_in : in std_logic;
clk : in std_logic;
rst : in std_logic;
sync_out : out std_logic
);
end;
architecture a of sync_2ff is
begin
signal ff1, ff2: std_logic;
-- It's nice to let the synthesizer know what you're doing. Altera's way of doing it as follows:
ATTRIBUTE altera_attribute : string;
ATTRIBUTE altera_attribute OF ff1 : signal is "-name SYNCHRONIZER_IDENTIFICATION ""FORCED IF ASYNCHRONOUS""";
ATTRIBUTE altera_attribute OF a : architecture is "-name SDC_STATEMENT ""set_false_path -to *|sync_2ff:*|ff1 """;
-- also set the 'preserve' attribute to ff1 and ff2 so the synthesis tool doesn't optimize them away
ATTRIBUTE preserve: boolean;
ATTRIBUTE preserve OF ff1: signal IS true;
ATTRIBUTE preserve OF ff2: signal IS true;
synchronizer: process(clk, rst)
begin
if rst = '1' then
ff1 <= '0';
ff2 <= '0';
else if rising_edge(clk) then
ff1 <= async_in;
ff2 <= ff1;
sync_out <= ff2;
end if;
end process synchronizer;
end sync_2ff;
Connect the physical pin for the N64 controller's rx data line to the async_in input of the synchronizer, and connect the sync_out signal to your UART's rxd input.
Unsynchronized signals can cause weird issues. Make sure any input connected to an FPGA element that isn't synchronized to the clock of the process reading the signal is synchronized. This includes pushbuttons, UART 'rx' and 'cts' signals... anything that is not synchronized to the clock that the FPGA is using to sample the signal.
(An aside: I wrote the page at www.mixdown.ca/n64dev many years ago. I just realized that I broke the link when I last updated the site and will fix it in the morning when I'm back at a computer. I had no idea so many people used that page!)
the rising_edge() parameter is only really for clock signals. One option would be the following:
clk_proc: process( clk, switch1, switch0 )
begin
if switch1 = '1' then
counter <= ( others => '0' );
elseif rising_edge( clk ) then
if switch0 = '1' then
counter <= counter + 1;
end if;
end if;
end process;
This is known as an asynchronously reset process, which means that it'll reset the counter whenever reset (switch1) is high, regardless of clock state. A synchronously reset process would look the same as your second example:
clk_proc: process( clk, switch1, switch0 )
begin
if rising_edge( clk ) then
if switch1 = '1' then
counter <= ( others => '0' );
elsif switch0 = '1' then
counter <= counter + 1;
end if;
end if;
end process;
You did state though that your second example didn't work as expected. My suspicion is that this is because the signals driving it are switches rather than clocked logic signals. Switches don't actually switch instantaneously, instead bouncing between on and off a few times before settling. You need to implement some sort of debounce process to produce a signal which is synchronous with your clock and can control your timer.
It's also worth mentioning that FPGA design is a lot easier if you simulate stuff first. Xilinx ISE includes a simulator - create a testbench and use it! That lets you easily see what's happening in your implementation before you ever get near hardware.
Best Answer
It is possible to drive a signal from two modules.
However, it is not straightforward; the two modules have to cooperate - if one drives '1' and the other '0' at the same time, you have created a short circuit across the power supply, and you can potentially damage the device. In simulation, thankfully, the results are less dramatic!
Two ways to do so; and the reason not to use either of them inside an FPGA.
The first way is the traditional "wired AND" where there is a weak '1' permanently connected to the signal. Traditionally this was a resistor connected to +5V; in VHDL you might say
Load_Divider <='H';
in the toplevel design. H and L are weak versions of '1' and '0'.Now every driver can either pull it low, or turn off
('Z' means the high-Z or high impedance state, i.e. turn off the driver).
If ALL the modules drive Z, the output is 'H' (equal to '1').
The second way is called a tri-state bus. Here either module may drive 0, 1 or Z onto the bus. However, you the designer MUST make sure that when one module is driving '0' or '1', ALL the other modules are driving 'Z', to prevent the short circuit and damage mentioned above. That requires the cooperation of all the modules in some way:
Either of these techniques are valid ways to communicate between separate FPGAs and other chips (memories, CPUs) on your board. But inside an FPGA there are no tri-state signals (only on its I/O pins) so if you use either technique above, the synthesis tools translate it into an equivalent signal without the tri-states.
For example the first technique (wired-AND) might translate to
where you can see that each signal has only one driver. So why not write that in the first place?