Sei sulla pagina 1di 18

-----------

Contents
ECE 271, Design Project, Group 15
Carson Hannibal, Jack Woods, Mohamed Eldebri, Cory Hayes, Sean Gillen

1 Project Description
June 9th, 2017

2 High Level Description 3


2.1 VCR Receiver Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.1.1 Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.2 Holder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.3 Gatekeeper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.4 Compare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.5 Compare_To_Parallel_Shift . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.6 Code_To_NES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Nintendo 64 Controller Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2.1 Clock_Stepper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.2 N64Decoder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.3 N64Reader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.4 controller_array_cycler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.5 flipper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.6 latch_decider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.7 poll_read_SM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.8 shift_register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3 8 Button Board & NES Console Interface Module . . . . . . . . . . . . . . . . . . . 9

A SystemVerilog Files 11
A.1 Button Board Emulation of NES Controller . . . . . . . . . . . . . . . . . . . . . . 11
A.2 VCR Remote Emulation of NES Controller . . . . . . . . . . . . . . . . . . . . . . 11
A.3 N64 SV Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

B Simulation Files (Do scripts) 17


B.1 Button Board . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
B.2 N64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
B.3 VCR Remote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

1
1 Project Description
Inputs: This design interfaces between a variety of inputs (a VCR remote, an N64 controller,
and a 272 Button board), and an NES game console. The input is selected by series System Verilog
case statements, which determine which controller is connected. These switches are active LOW.
If more than one switch is enabled, then the VCR remote is given priority, just like the example
given in class.
Outputs: There is one output to the NES console. The NES sends a HIGH latch to the FPGA,
which "latches" a shift register in the button_board_controller. The console proceeds to send 8
clock pulses, and the shift register responds by transmitting the bits corresponding to each button
on the controller.

Figure 1: Hardware Diagram

This document contains information regarding:


1. Power and ground on the output consoles
2. Pin numbers being used on the FPGA

3. Descriptions of how the wires are connected


4. High and low level descriptions of each module used in the design

2
2 High Level Description
Inputs: This interfaces one of three inputs based on user selection with the NES console. The
circuit is compatible with three different forms of input: a 272 button board, an N64 Controller,
or a VCR IR Receiver paired with a universal remote.
Outputs: This outputs a simulated NES Controller output to the NES Console.

Figure 2: This is the top level diagram for the logic associated with our project.

2.1 VCR Receiver Module


Inputs: This module receives a 2.08MHz clock signal, and a 32-bit infrared signal from a VCR
remote using the DVD protocol.

Outputs: This module produces an 8-bit parallel active-low output.

As can be seen in figure 3, the top level diagram for the VCR module receives waveform input
directly from an infrared receiver, which is connected to ground and a pull-up resistor. The wave-
form data is passed to two modules: counter and compare_to_parallel_shift.

Figure 3: This is the top-level diagram for the VCR module.

Firstly, counter begins to increment result by one whenever it is triggered by the 2.09MHz
clock. It has an active low reset, which sets the output to 0 when ir_in is LOW. A sample ir_in
waveform is provided in figure 7. Notice that bits are transmitted by manipulating the period of
the 38KHz square carrier wave, and that new bits are sent after each falling edge of the wave.
Arbitrarily, let’s assume that long pulses are 1s and short pulses are 0s.

Since s = f1 , the period length of our 2.08MHz clock signal was f = 2,080,000
1
= 4.8 ∗ 10−7 sec-
onds. CSV files provided by the instructor (Mr. Matt Shuman - Oregon State University College
of Engineering) revealed that a 1 was represented by a 0.0016 second HIGH pulse, and a 0 was
represented by a 0.0005 second LOW pulse. With the aforementioned information, we were able
to calculate the number of "counts" counter would output for a 1 and a 0 respectively.

0.0016 0.0005
c1 = 0.00000048 = 3, 333 c0 = 0.00000048 = 1, 041

3
Figure 4: Sample VCR remote IR waveform.

Next, we chose 2,000 as a number which will differentiate between 1s and 0s with sufficient
padding between the two. This number is stored inside of the register labeled gatekeeper, and is
used by compare to differentiate between inputs. The output of compare, when tested right before
the falling edge of ir_in, reveals whether a 1 or a 0 was transmitted by the VCR remote. This
output is fed directly into a shift register labeled compare_to_parallel_shift, which is triggered
by the falling edge of ir_in.

Note that as ir_in falls, counter is reset to 0. To prevent the false 0 from propagating through
the circuit, a register labeled holder holds the value for 1 additional clock cycle. This ensures that
the shift register always reads the correct input as it changes with respect to counter’s value.

The final parallel output is produced by a LUT labeled code_to_nes, which compares the
32 bit parallel signal from compare_to_parallel_shift to a set of predetermined values, which
correspond with buttons on an NES controller. This contains our extra feature, which allows two
options specific to the NES game Super Mario Bros., which inputs the same button sequence on
the NES controller that would allow Mario to run right or run right while jumping.

2.1.1 Counter
Inputs: The module receives a 2.08 MHZ clock signal, and an active-low reset input from the
IR receiver.

Output: Synchronously supplies a 12-bit output to /verb|holder|, which stores the value for 1
clock cycle.

We used this 12-bit counter to measure the period of the input square wave. The active-low

4
reset triggers after the falling edge of the input, which sets the counter to 0 and prepares it for the
next incoming bit.

Figure 5: Counter Simulation Waveforms.

2.1.2 Holder
Inputs: This requires a 12-bit bus labeled num.

Outputs: The num input propagates through each clock cycle.

This module is just a register, and is used to delay the input into compare.

2.1.3 Gatekeeper
Inputs: None

Outputs: The gatekeeper module outputs 20002 on its 12-bit bus output.

This module is just a register, and is used as a constant for comparison by the compare module.
2000 is an arbitrary number of "counts" used to differentiate between a 1 and a 0 pulse from the
VCR remote. For more information, please reference figure 7 and the description which follows.

2.1.4 Compare
Inputs: Two, 12-bit bus inputs labeled p and q.

Outputs: A 1 bit interpretation of the data received by the IR receiver.

This module compares the input from counter to the constant stored in gatekeeper. If the
value from counter exceeds the value stored in gatekeeper, the compare module outputs a 1.
Otherwise, the module outputs a 0.

The 1 or 0 outputted by this module is the current bit of data being received by the IR receiver.

Figure 6: Compare Simulation Waveforms.

2.1.5 Compare_To_Parallel_Shift
Inputs: 2.08MHz clock, and 1 bit input from compare.

Outputs: A 32-bit bus, containing all of the data included in one complete waveform from the
VCR remote.

5
This shift register converts the parallel input from the IR receiver into a parallel output. The
register stores 32 bits, which is the length of one "word" from the VCR remote.

Figure 7: Compare_to_parallel_shift Simulation Waveforms.

2.1.6 Code_To_NES
Inputs: 32-bit parallel input

Outputs: The 8-bit output is determined with respect to the 32 bit input.

This module is essentially a LUT (Look Up Table). Each 32-bit word corresponds to a particular
button press on the VCR remote. The LUT compares the input to the table of constants it stores,
and outputs an 8-bit combination which corresponds to a button press on an NES remote. The
8-bit output is active-low.

Figure 8: Code_to_NES Simulation Waveforms.

2.2 Nintendo 64 Controller Module


Inputs: The module would receive a 2 MHZ clock as an input, it already includes a module
for simulating controller input so the data input is an internal signal in the top module. It also
includes the module for dividing the clock frequency.
Output: Synchronously sends an 8 bit output to the NES module, with 0 meaning a button
is pressed, 1 meaning a button is not pressed. Also sends a latch to the NES module to indicate
whether we are in the write state or not.
We used a 4 kHZ counter to cycle between 3 states. State 0 indicates that we’re now sending
the polling signal. State 1 means we are reading controller input. State 2 means we’re now sending
controller input to the NES module, so that it can asynchronously send the data to the NES
console.

Figure 9: High Level Diagram of N64 Interfacing With NES console

6
Figure 10: High level Simulation showing state 0

Figure 11: High level Simulation showing state 1

Figure 12: High level Simulation showing state 2

2.2.1 Clock_Stepper
Inputs: The clock stepper receives a 2 MHZ clock input and divides it into 2 outputs.
Outputs: The 2 outputs are the 1 MHZ clock and 4 kHZ clock where the first is used for
modules inside of the three states and the latter is used to cycle between the three states.

2.2.2 N64Decoder
Inputs: receives a serial input from the shift_register module, which is almost identical to input
from an N64 controller.
Output: 8 bit output indicating the one’s complement of NES buttons, which gets inverted
before being sent to the flipper module. The simulation shows how the decoder responded when

7
Figure 13: The simulation shows how clock frequencies are divided so that they can be used in
other modules.

it was given an input of 001. It reads the input every 4 microseconds and assigns it to the
corresponding NES button.

Figure 14: N64Reader sending the polling signal.

2.2.3 N64Reader
Inputs: This receives the data wire, which is a tristate port that accepts input and sends output.
Also receives the 1 MHZ clock and a reset.
Output: This outputs the polling signal to the data wire, then drives the data wire to a float
one the polling signal is done.

Figure 15: N64Reader sending the polling signal.

2.2.4 controller_array_cycler
This module was made to emulate N64 signals for testing purposes.
Inputs: Receives a 4 kHZ clock, the state of the system in a 3 bit input and a reset.
Output: Multiple 33 bit signals emulating the signals outputted by an N64 controller.

2.2.5 flipper
The module was made to flip the bits so that A is the most significant bit, instead of the least
significant bit.
Inputs: 8 bit input indicating the buttons pressed on the NES, where A is the least significant
bit.
Outputs: 8 bit flipped output, with A being the most significant bit.

8
Figure 16: 33 bit outputs for testing.

Figure 17: Flipping the input.

2.2.6 latch_decider
This module was used for testing an NES console input to the NES controller. Inputs: The 2
bit state bus, 1 MHZ clock, a reset.
Outputs: A latch output for the NES module to indicate when to send the button data to the
NES console. The latch will turn HIGH then remain high until 12 positive edges of the clock or
the state changes. In the simulation below it remained HIGH until the 12 positive edges of the
clock.

Figure 18: Latch stops after 12 positive edges.

2.2.7 poll_read_SM
Inputs: This is a counter that takes in a 4 kHZ clock and a reset.
Output: It outputs a 2 bit bus indicating the state of the system. A state of 0 indicates the
polling signal stage. A state of 1 means we’re now reading the controller input. A state of 2
indicates we’re sending input to the NES module.

2.2.8 shift_register
Inputs: This module was made for testing purposes. The module converts a parallel 33 bit
input into a serial output. The module also takes in a 1 MHZ clock, a reset and a 2 bit input
representing the state.
Output: Serial output similar to N64 controller output.

2.3 8 Button Board & NES Console Interface Module


This module simulates an NES controller using an active-low eight button board with each
button corresponding to one of the eight buttons on the NES controller.
Inputs: As inputs, the module takes in a latch, clock signal, and eight bit bus for the buttons.
When the latch goes high, it signals a shift register in this module to load in all of the button
inputs, where the most significant bit is A, followed by B, Select, Start, Up, Down, Left, and Right
as the least significant bit. When the clock goes high, the shift register shifts left all of its bits by
one, and resets the least significant bit to 0.
Outputs: Single bit data line that passes the serialized button inputs to the NES console. This
data line is assigned in Verilog to the most significant bit of the shift register, which is A when the
latch signal is set and Right during the last clock signal.

9
Figure 19: Simulation of state counter.

Figure 20: Simulation of shift_register module.

Figure 21: button_board_controller block diagram

Figure 22: Simulation of button_board_controller module.

10
A SystemVerilog Files
A.1 Button Board Emulation of NES Controller
1 module t o p (
2 input l o g i c clk ,
3 input l o g i c latch ,
4 input l o g i c [ 7 : 0 ] buttons ,
5
6 output logic sout ) ;
7
8
9 reg [7:0] q;
10
11 // b u t t o n not pressed = logic 1
12
13 // s t e p s :
14 // when l a t c h i n p u t g o e s low−>h i g h , a s y n c h r o n o u s l y load button states into register
15 // O r d e r o f s h i f t : A, B , S e l , S t a r t , U, D, L , R
16
17 always_ff@ ( posedge clk , posedge latch )
18 i f ( latch )
19 q <= b u t t o n s ;
20 else
21 q <= q << 1 ;
22 assign sout = q [ 7 ] ;
23
24 endmodule

A.2 VCR Remote Emulation of NES Controller


1 module counter (
2 input l o g i c clk ,
3 input l o g i c reset ,
4 output l o g i c [ 1 1 : 0 ] result ) ;
5
6 always @ ( posedge c l k )
7 begin
8 i f ( r e s e t ) r e s u l t <= 1 2 ’ b 0 0 0 0 0 0 0 0 0 0 0 0 ;
9 e l s e r e s u l t <= r e s u l t + 1 ;
10 end
11 endmodule
12
13 module holder (
14 input l o g i c clk ,
15 i n p u t l o g i c [ 1 1 : 0 ] num ,
16 o u t p u t l o g i c [ 1 1 : 0 ] compare ) ;
17
18 always_ff @ ( posedge c l k )
19 compare <= num ;
20 endmodule
21
22 module gatekeeper (
23 output l o g i c [11:0] gate ) ;
24
25 assign gate = 12 ’ b11111010000 ;
26 endmodule
27
28 module compare (
29 input l o g i c [ 1 1 : 0 ] p ,
30 input l o g i c [ 1 1 : 0 ] q ,
31 output l o g i c s i g n a l ) ;
32
33 always_comb
34 i f ( p > q ) s i g n a l <= 1 ;
35 e l s e s i g n a l <= 0 ;
36 endmodule
37
38 module compare_to_parallel_shift (
39 i n p u t l o g i c s_in ,
40 input l o g i c clk ,
41 output l o g i c [ 3 1 : 0 ] code ) ;
42
43 logic [31:0] first ;
44 logic [31:0] next ;
45
46 always_ff @ ( negedge c l k )
47 begin
48 i f ( clk )
49 f i r s t <= 0 ;
50 else
51 f i r s t <= n e x t ;
52 end
53
54 assign n e x t = { s_in , first [31:0]};
55
56 assign code = next ;
57 endmodule

1 module code_to_NES (
2 input l o g i c [ 3 1 : 0 ] code ,
3 output l o g i c [ 7 : 0 ] buttons ) ;
4
5 always_comb
6 c a s e ( code )
7 32 ’ b10011100011000111000000001111111 : buttons = 8 ’ b00001000 ; // 2 on remote is up
on t h e NES c o n t r o l l e r
8 32 ’ b10011100011000110010000011011111 : buttons = 8 ’ b00000010 ; // 4 i s l e f t
9 32 ’ b10011100011000111010000001011111 : buttons = 8 ’ b00000100 ; // 5 i s down
10 32 ’ b10011100011000110110000010011111 : buttons = 8 ’ b00000001 ; // 6 i s r i g h t
11 32 ’ b10011100011000111110100000010111 : buttons = 8 ’ b01000000 ; // C h a n n e l up i s B
12 32 ’ b10011100011000110001100011100111 : buttons = 8 ’ b10000000 ; // C h a n n e l down i s A
13 32 ’ b10011100011000111001000001101111 : buttons = 8 ’ b00010000 ; // 8 i s S t a r t
14 32 ’ b10011100011000110101000010101111 : buttons = 8 ’ b00100000 ; // 9 i s S e l e c t
15 32 ’ b10011100011000110101001010101101 : buttons = 8 ’ b01000001 ; //Up i s B and R i g h t
( make Mario r u n )
16 32 ’ b10011100011000110110001010011101 : buttons = 8 ’ b11000001 ; //Down is B, Right ,
and A ( Mario r u n n i n g jump )
17 endcase
18 endmodule

11
1 module remote_NES_controller (
2 input l o g i c ir_in ,
3 i n p u t l o g i c NES_latch ,
4 i n p u t l o g i c NES_clk ,
5 o u t p u t l o g i c NES_data ) ;
6
7 logic clk ;
8 logic [ 5 : 0 ] count_hold ;
9 logic [ 5 : 0 ] hold_comp ;
10 logic [ 5 : 0 ] gate_comp ;
11 logic encode ;
12 logic [ 3 1 : 0 ] remote ;
13 logic [7:0] controller ;
14
15 counter count (
16
17 . clk ( clk ) ,
18 . reset ( ir_in ) ,
19 . r e s u l t ( count_hold )
20
21 );
22
23 holder hold (
24
25 . num ( c o u n t _ h o l d ) ,
26 . clk ( clk ) ,
27 . compare ( hold_comp )
28
29 );
30
31 gatekeeper gate (
32
33 . g a t e ( gate_comp )
34
35 );
36
37 compare comp (
38
39 . p ( hold_comp ) ,
40 . q ( gate_comp ) ,
41 . s i g n a l ( encode )
42
43 );
44
45 compare_to_parallel_shift (
46
47 . s_in ( encode ) ,
48 . clk ( ir_in ) ,
49 . code ( remote )
50
51 );
52
53
54 code_to_NES translate (
55
56 . code ( remote ) ,
57 . buttons ( c o n t r o l l e r )
58
59 );
60
61 top ending (
62
63 . buttons ( c o n t r o l l e r ) ,
64 . l a t c h ( NES_latch ) ,
65 . c l k ( NES_clk ) ,
66 . s o u t ( NES_data )
67
68 );
69
70 OSCH #(" 2 . 0 8 " ) osc_int ( // " 2 . 0 8 " specifies the operating f r e q u e n c y , 2 . 0 8 MHz .
71 // O t h e r c l o c k f r e q u e n c i e s c a n be
f o u n d i n t h e MachX02 ’ s
documentation
72 . STDBY( 1 ’ b0 ) , // S p e c i f i e s a c t i v e s t a t e
73 . OSC( c l k ) , // O u t p u t s c l o c k s i g n a l t o ’ c l k ’ n e t
74 . SEDSTDBY ( ) ) ; // L e a v e s SEDSTDBY p i n u n c o n n e c t e d
75
76 endmodule

A.3 N64 SV Files


1 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
2 // Company : Oregon S t a t e U n i v e r s i t y
3 // E n g i n e e r : Matthew Shuman
4 //
5 // C r e a t e Date : 05/10/2016
6 // D e s i g n Name : demo2016
7 // Module Name : ClockDivider
8 // P r o j e c t Name :
9 // T a r g e t D e v i c e s : MachX02
10 // T o o l v e r s i o n s : L a t t i c e Diamond 3 . 7
11 // D e s c r i p t i o n : C l o c k d i v i d e r t h a t r e d u c e s t h e 2 . 0 8 MHz c l o c k t o more u s e f u l f r e q u e n c i e s . The u n u s e d
p o r t i o n s o f t h e c o u n t e r w i l l be e l i m i n a t e d by t h e s y n t h e s i z e r .
12 //
13 // D e p e n d e n c i e s :
14 //
15 // R e v i s i o n :
16 // R e v i s i o n 0 . 0 1 − F i l e C r e a t e d
17 // a d d i t i o n a l Comments :
18 //
19 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
20 module C l o c k D i v i d e r (
21 i n p u t l o g i c clock_2MHz , // t h e c l o c k d r i v i n g t h e c o u n t e r
22 input l o g i c reset_n , // a c t i v e l o w r e s e t
23 o u t p u t l o g i c clock_1MHz , //
24 o u t p u t l o g i c clock_512KHz , //
25 o u t p u t l o g i c clock_256KHz , //
26 o u t p u t l o g i c clock_128KHz , //
27 o u t p u t l o g i c clock_64KHz , //
28 o u t p u t l o g i c clock_32KHz , //
29 o u t p u t l o g i c clock_16KHz , //
30 o u t p u t l o g i c clock_8KHz , //
31 o u t p u t l o g i c clock_4KHz , //
32 o u t p u t l o g i c clock_2KHz , //

12
33 output logic clock_1KHz , //
34 output logic clock_512Hz , //
35 output logic clock_256Hz , //
36 output logic clock_128Hz , //
37 output logic clock_64Hz , //
38 output logic clock_32Hz , //
39 output logic clock_16Hz , //
40 output logic clock_8Hz , //
41 output logic clock_4Hz , //
42 output logic clock_2Hz , //
43 output logic clock_1Hz //
44 );
45
46 logic [20:0] count ;
47
48 always_ff@ ( posedge clock_2MHz , n e g e d g e r e s e t _ n )
49 if ( ! reset_n ) c o u n t <= 0 ;
50 else c o u n t <= c o u n t + 1 ;
51
52 assign clock_1MHz = c o u n t [ 0 ] ; //
53 assign clock_512KHz = c o u n t [ 1 ] ; //
54 assign clock_256KHz = c o u n t [ 2 ] ; //
55 assign clock_128KHz = c o u n t [ 3 ] ; //
56 assign clock_64KHz = c o u n t [ 4 ] ; //
57 assign clock_32KHz = c o u n t [ 5 ] ; //
58 assign clock_16KHz = c o u n t [ 6 ] ; //
59 assign clock_8KHz = c o u n t [ 7 ] ; //
60 assign clock_4KHz = c o u n t [ 8 ] ; //
61 assign clock_2KHz = c o u n t [ 9 ] ; //
62 assign clock_1KHz = c o u n t [ 1 0 ] ; //
63 assign clock_512Hz = count [ 1 1 ] ; //
64 assign clock_256Hz = count [ 1 2 ] ; //
65 assign clock_128Hz = count [ 1 3 ] ; //
66 assign clock_64Hz = count [ 1 4 ] ; //
67 assign clock_32Hz = count [ 1 5 ] ; //
68 assign clock_16Hz = count [ 1 6 ] ; //
69 assign c l o c k _ 8 H z = c o u n t [ 1 7 ] ; //
70 assign c l o c k _ 4 H z = c o u n t [ 1 8 ] ; //
71 assign c l o c k _ 2 H z = c o u n t [ 1 9 ] ; //
72 assign clock_1Hz = count [ 2 0 ] ;
73
74 endmodule

1 // c l o c k _ s t e p p e r . s v
2 // Module f o r d i v i d i n g a 1 MHZ c l o c k
3
4
5
6 module Clock_Stepper
7 (
8 i n p u t l o g i c clk_2MHZ ,
9 input l o g i c reset_n ,
10 o u t p u t l o g i c clk_1MHZ ,
11 o u t p u t l o g i c clk_4kHZ
12 );
13
14 logic [7:0] count ;
15
16 a l w a y s _ f f @ ( p o s e d g e clk_2MHZ , n e g e d g e r e s e t _ n )
17 begin
18 c o u n t <= c o u n t + 1 ;
19 i f ( ! reset_n )
20 begin
21 clk_1MHZ <= 0 ;
22 clk_4kHZ <= 0 ;
23 c o u n t <= 0 ;
24 end
25 else
26 begin
27 clk_1MHZ <= ~clk_1MHZ ;
28 i f ( c o u n t >= 2 5 0 )
29 begin
30 c o u n t <= 0 ;
31 clk_4kHZ <= ~clk_4kHZ ;
32 end
33 end
34 end
35
36 endmodule

1 // N64Decoder . s v
2 // Module f o r c o n v e r t i n g s e r i a l i n p u t f r o m t h e N64 DATA w i r e to a parallel inverted // NES o u t p u t .
3 module N64Decoder ( i n p u t l o g i c c l k , r e s e t , s i n , [ 3 : 0 ] c o u n t ,
4 o u t p u t l o g i c [ 7 : 0 ] NESButtons ) ;
5
6 always_comb
7 c a s e ( count )
8 4 : NESButtons [ 0 ] = s i n ; //A
9 8 : NESButtons [ 1 ] = s i n ; // B
10 1 2 : NESButtons [ 2 ] = s i n ;
11 1 6 : NESButtons [ 3 ] = s i n ;
12 2 0 : NESButtons [ 4 ] = s i n ;
13 2 4 : NESButtons [ 5 ] = s i n ;
14 2 8 : NESButtons [ 6 ] = s i n ;
15 3 2 : NESButtons [ 7 ] = s i n ;
16 3 6 : NESButtons [ 1 : 0 ] = s i n ;
17 4 0 : NESButtons [ 1 : 0 ] = s i n ;
18 4 4 : NESButtons [ 1 : 0 ] = s i n ;
19 4 8 : NESButtons [ 1 : 0 ] = s i n ;
20 5 2 : NESButtons [ 4 ] = s i n ;
21 5 6 : NESButtons [ 5 ] = s i n ;
22 6 0 : NESButtons [ 6 ] = s i n ;
23 6 4 : NESButtons [ 7 ] = s i n ;
24 6 8 : NESButtons [ 6 ] = s i n ;
25 7 2 : NESButtons [ 6 ] = s i n ;
26 7 6 : NESButtons [ 6 ] = s i n ;
27 8 0 : NESButtons [ 6 ] = s i n ;
28 8 4 : NESButtons [ 7 ] = s i n ;
29 8 8 : NESButtons [ 7 ] = s i n ;
30 9 2 : NESButtons [ 7 ] = s i n ;
31 9 6 : NESButtons [ 7 ] = s i n ;
32 1 0 0 : NESButtons [ 4 ] = s i n ;
33 1 0 4 : NESButtons [ 4 ] = s i n ;
34 1 0 8 : NESButtons [ 4 ] = s i n ;

13
35 1 1 2 : NESButtons [ 4 ] = sin ;
36 1 1 6 : NESButtons [ 5 ] = sin ;
37 1 2 0 : NESButtons [ 5 ] = sin ;
38 1 2 4 : NESButtons [ 5 ] = sin ;
39 1 2 8 : NESButtons [ 5 ] = sin ;
40 d e f a u l t NESButtons = 0;
41 endcase
42 endmodule

1 // N64Reader . s v
2 // Module f o r s e n d i n g a polling signal to t h e DATA w i r e
3
4 module N64Reader ( i n p u t l o g i c clk_1MHZ , r e s e t _ n ,
5 input l o g i c [ 1 : 0 ] state ,
6 i n o u t N64Data ) ;
7
8
9 logic [ 8 : 0 ] outer_counter ;
10 logic [ 1 : 0 ] inner_counter ;
11 logic signal ;
12
13 a l w a y s _ f f @ ( p o s e d g e clk_1MHZ , n e g e d g e r e s e t _ n )
14 i f ( ! r e s e t _ n | | s t a t e != 2 ’ b00 ) o u t e r _ c o u n t e r <= 0 ;
15 e l s e i f ( i n n e r _ c o u n t e r == 3 )
16 o u t e r _ c o u n t e r <= o u t e r _ c o u n t e r + 1 ;
17
18 a l w a y s _ f f @ ( p o s e d g e clk_1MHZ , n e g e d g e r e s e t _ n )
19 i f ( ! r e s e t _ n | | s t a t e != 2 ’ b00 ) i n n e r _ c o u n t e r <= 0 ;
20 e l s e i n n e r _ c o u n t e r <= i n n e r _ c o u n t e r + 1 ;
21
22 always_comb
23 i f ( o u t e r _ c o u n t e r <= 6 )
24 // / l o g i c f o r s e n d i n g a z e r o
25 i f ( i n n e r _ c o u n t e r <= 2 )
26 signal = 0;
27 else
28 signal = 1;
29 else
30 // l o g i c f o r s e n d i n g a o n e
31 i f ( i n n e r _ c o u n t e r >= 1 )
32 signal = 1;
33 else
34 signal = 0;
35
36
37 a s s i g n N64Data = ( s t a t e == 2 ’ b00 && o u t e r _ c o u n t e r < 9 ) ? signal : 1 ’ bZ ;
38 endmodule

1 // N64_to_NES_top . s v Highest level of N64−NES i n t e r f a c i n g


2
3 module highest_level_n64
4 (
5 input l o g i c clk_i ,
6 input l o g i c reset_n ,
7 output l o g i c sout
8 );
9
10 logic clk_1MHZ ;
11 logic latch ;
12 logic [ 7 : 0 ] buttons ;
13
14
15 N64_to_NES_top top_top
16 (
17 . clk_i ( clk_i ) ,
18 . reset_n ( reset_n ) ,
19 . clk_1MHZ ( clk_1MHZ ) ,
20 . latch ( latch ) ,
21 . FlippedButtons ( buttons )
22 );
23
24 button_to_NES send_1
25 (
26 . c l k ( clk_1MHZ ) ,
27 . latch ( latch ) ,
28 . buttons ( buttons ) ,
29 . sout ( sout )
30 );
31
32 endmodule
33
34 module N64_to_NES_top
35 (
36 input l o g i c clk_i ,
37 input l o g i c reset_n ,
38 o u t p u t l o g i c clk_1MHZ ,
39 output l o g i c latch ,
40 output l o g i c [ 7 : 0 ] FlippedButtons
41 );
42
43
44 l o g i c clk_4kHZ ;
45 logic [ 1 : 0 ] state ;
46 t r i N64Data ;
47 l o g i c [ 3 2 : 0 ] gen_controller_res ;
48 l o g i c [ 7 : 0 ] NESButtons ;
49
50
51 Clock_Stepper c l k _ d i v i d e r
52 (
53 . clk_2MHZ ( c l k _ i ) ,
54 . reset_n ( reset_n ) ,
55 . clk_1MHZ ( clk_1MHZ ) ,
56 . clk_4kHZ ( clk_4kHZ )
57 );
58
59 N64Reader r e a d e r 1
60 (
61 . clk_1MHZ ( clk_1MHZ ) ,
62 . reset_n ( reset_n ) ,
63 . state ( state ) ,
64 . N64Data ( N64Data )
65 );
66

14
67 controller_to_NES_shift register_1
68 (
69 . clk_1MHZ ( clk_1MHZ ) ,
70 . reset_n ( reset_n ) ,
71 . bit_array ( gen_controller_res ) ,
72 . state ( state ) ,
73 . s o u t ( N64Data )
74 );
75
76 poll_read_SM SM_1
77 (
78 . clk_4kHZ ( clk_4kHZ ) ,
79 . reset_n ( reset_n ) ,
80 . state ( state )
81 );
82
83 controller_array_cycler cycler_1
84 (
85 . clk_4kHZ ( clk_4kHZ ) ,
86 . reset_n ( reset_n ) ,
87 . is_idle ( state ) ,
88 . controller_array ( gen_controller_res )
89 );
90
91 N64Decoder t r a n s l a t e _ 1
92 (
93 . clk_1MHZ ( clk_1MHZ ) ,
94 . reset_n ( reset_n ) ,
95 . s i n ( N64Data ) ,
96 . is_reading ( state ) ,
97 . NESButtons ( NESButtons )
98 );
99
100
101
102 flipper flip_1
103 (
104 . c l k ( clk_1MHZ ) ,
105 . reset_n ( reset_n ) ,
106 . i n (~ NESButtons ) ,
107 . state ( state ) ,
108 . out ( FlippedButtons )
109 );
110
111 latch_decider enabler_1
112 (
113 . c l o c k ( clk_1MHZ ) ,
114 . reset_n ( reset_n ) ,
115 . state ( state ) ,
116 . latch ( latch )
117 );
118 endmodule

1 // Module f o r s e n d i n g p a r a l l e l 33 b i t o u t p u t to simulate N64 controller data


2 module c o n t r o l l e r _ a r r a y _ c y c l e r
3 (
4 i n p u t l o g i c clk_4kHZ ,
5 input l o g i c reset_n ,
6 input l o g i c [ 1 : 0 ] is_idle ,
7 output l o g i c [ 3 2 : 0 ] c o n t r o l l e r _ a r r a y
8 );
9
10 logic [3:0] count_state ;
11
12 a l w a y s _ f f @ ( p o s e d g e clk_4kHZ , n e g e d g e r e s e t _ n )
13 begin
14 i f ( ! r e s e t _ n | | i s _ i d l e != 2 ’ b10 )
15 c o u n t _ s t a t e <= 0 ;
16 else
17 c o u n t _ s t a t e <= c o u n t _ s t a t e + 1 ;
18 end
19
20 always_comb
21 begin
22 case ( count_state )
23 4 ’ b0000 : c o n t r o l l e r _ a r r a y = 3 3 ’ b101000000000000000001111000000001 ;
// A, Z and X a x i s t o t h e l e f t
24 4 ’ b0001 : c o n t r o l l e r _ a r r a y = 3 3 ’ b010000000000000000001111000011111 ;
// x and y movement w/ B b u t t o n
25 4 ’ b0010 : c o n t r o l l e r _ a r r a y = 3 3 ’ b100000000000000000001111000011111 ;
// x and y movement w/ A b u t t o n
26 4 ’ b0011 : c o n t r o l l e r _ a r r a y = 3 3 ’ b001000000000000000001111000011111 ;
// x and y movement w/ Z b u t t o n
27 4 ’ b0100 : c o n t r o l l e r _ a r r a y = 3 3 ’ b001000000000100100000000000000001 ;
// camera movement up and r i g h t
28 4 ’ b0101 : c o n t r o l l e r _ a r r a y = 3 3 ’ b001000000000011000000000000000001 ;
// camera movement down and l e f t
29 d e f a u l t : c o n t r o l l e r _ a r r a y = 33 ’ b000000000000000000001111000011111 ;
// x and y movement
30 endcase
31 end
32 endmodule

1 // f l i p p e r . s v
2 // Module f o r f l i p p i n g an i n p u t and o u t p u t t i n g t h e f l i p p e d r e p r e s e n t a t i o n
3 module f l i p p e r ( i n p u t l o g i c c l k , [ 7 : 0 ] i n , [ 1 : 0 ] s t a t e , r e s e t _ n ,
4 output l o g i c [ 7 : 0 ] out ) ;
5
6
7
8
9 always_ff @ ( posedge c l k )
10 i f ( s t a t e == 2 ’ b10 ) b e g i n
11 o u t [ 0 ] <= i n [ 7 ] ;
12 o u t [ 1 ] <= i n [ 6 ] ;
13 o u t [ 2 ] <= i n [ 5 ] ;
14 o u t [ 3 ] <= i n [ 4 ] ;
15 o u t [ 4 ] <= i n [ 3 ] ;
16 o u t [ 5 ] <= i n [ 2 ] ;
17 o u t [ 6 ] <= i n [ 1 ] ;
18 o u t [ 7 ] <= i n [ 0 ] ;
19 end
20 e l s e i f ( s t a t e != 2 ’ b10 )
21 o u t <= 0 ;

15
22
23 endmodule

1 // l a t c h _ d e c i d e r . s v
2 // Module t o s i m u l a t e an NES c o n s o l e by sending a latch output to t h e NES module
3 // i n s t a t e 2 .
4 module l a t c h _ d e c i d e r (
5 input l o g i c clock , reset_n ,
6 input l o g i c [ 1 : 0 ] state ,
7 output l o g i c l a t c h ) ;
8 l o g i c [ 4 : 0 ] count ;
9
10
11 always_ff @ ( posedge clock , negedge reset_n )
12 i f ( ! r e s e t _ n | | s t a t e != 2 ’ b10 ) b e g i n
13 l a t c h <= 0 ;
14 c o u n t <= 0 ;
15 end
16
17 else i f ( state == 2 ’ b10 && c o u n t >= 1 1 )
18 latch <= 0 ;
19 else begin
20 latch <= 1 ;
21 count <= c o u n t + 1 ;
22 end
23
24
25 endmodule

1 // poll_read_SM . s v
2 // c o u n t e r module t o c h a n g e s t a t e s o f t h e s y s t e m t o 3 s t a t e s (0 , 1, 2)
3 module poll_read_SM ( // e x a m p l e o f a Moore t y p e s t a t e m a c h i n e
4 i n p u t l o g i c clk_4kHZ ,
5 input l o g i c reset_n ,
6
7 output logic [1:0] state // The state outputted by this state machine
8 );
9
10 // n e x t s t a t e r e g i s t e r
11 l o g i c [ 1 : 0 ] state_n ;
12
13 // e a c h p o s s i b l e v a l u e of the s t a t e register is given a u n i q u e name for easier use later
14 p a r a m e t e r S0 = 2 ’ b00 ; // P o l l i n g
15 p a r a m e t e r S1 = 2 ’ b01 ; // R e a d i n g
16 p a r a m e t e r S2 = 2 ’ b10 ; // I d l e
17
18 // a s y n c h r o n o u s r e s e t w i l l s e t t h e s t a t e t o t h e s t a r t , S0 , otherwise , the state is
changed
19 // on t h e p o s i t i v e e d g e o f t h e c l o c k s i g n a l
20 a l w a y s _ f f @ ( p o s e d g e clk_4kHZ , n e g e d g e r e s e t _ n )
21 begin
22 i f ( ! reset_n )
23 s t a t e = S0 ;
24 else
25 s t a t e = state_n ;
26
27 end
28
29 // t h i s s e c t i o n d e f i n e s what t h e n e x t s t a t e s h o u l d be f o r e a c h p o s s i b l e state . in this
30 // i m p l e m e n t a t i o n , i t s i m p l y r o t a t e s through each s t a t e a u t o m a t i c a l l y
31 always_ff @ (∗)
32 begin
33 case ( state )
34 S0 : s t a t e _ n = S1 ;
35 S1 : s t a t e _ n = S2 ;
36 S2 : s t a t e _ n = S0 ;
37
38 default : s t a t e _ n = S0 ;
39 endcase
40 end
41 endmodule

1 // s h i f t _ r e g i s t e r . sv
2 // changes the t e s t p a r a l l e l input from controller_array_cycler to a serial output
3
4 module controller_to_NES_shift
5 (
6 i n p u t l o g i c clk_1MHZ ,
7 input l o g i c reset_n ,
8 // i n p u t l o g i c s i n ,
9 input l o g i c [ 3 2 : 0 ] bit_array ,
10 input l o g i c [ 1 : 0 ] state ,
11 // o u t p u t l o g i c [ 3 2 : 0 ] q ,
12 output l o g i c sout
13 );
14 logic [ 1 : 0 ] signal_count ;
15 logic [ 5 : 0 ] bit_count ;
16 logic signal ;
17
18 a l w a y s _ f f @ ( p o s e d g e clk_1MHZ , n e g e d g e r e s e t _ n )
19 begin
20 i f ( ! r e s e t _ n | | s t a t e != 2 ’ b01 )
21 s i g n a l _ c o u n t <= 0 ;
22 else
23 s i g n a l _ c o u n t <= s i g n a l _ c o u n t + 1 ;
24 end
25
26
27 a l w a y s _ f f @ ( p o s e d g e clk_1MHZ , n e g e d g e r e s e t _ n )
28 begin
29 i f ( ! r e s e t _ n | | s t a t e != 2 ’ b01 )
30 b i t _ c o u n t <= 0 ;
31 e l s e i f ( s i g n a l _ c o u n t == 3 )
32 b i t _ c o u n t <= b i t _ c o u n t + 1 ;
33 end
34
35 always_comb
36 i f ( b i t _ a r r a y [ 3 2 − b i t _ c o u n t ] == 1 ) // s e n d HIGH s i g n a l
37 i f ( s i g n a l _ c o u n t >= 1 ) // o n e LOW, f o l l o w e d by 3 HIGH
38 signal = 1;
39 else
40 signal = 0;
41 else

16
42 i f ( s i g n a l _ c o u n t >= 3 ) // s e n d LOW s i g n a l
43 signal = 1; // 3 LOW, f o l l o w e d by 1 HIGH
44 else
45 signal = 0;
46
47 always_comb
48 i f ( s t a t e == 2 ’ b01 && b i t _ c o u n t <= 3 2 )
49 sout = s i g n a l ;
50 else
51 s o u t = 1 ’ bz ;
52 endmodule

1 module switch_top (
2 input clk_nes , input latch_nes ,
3 input [ 7 : 0 ] buttons ,
4 input [ 2 : 0 ] controller_switch ,
5 o u t p u t l o g i c data_to_NES ,
6 // N64 i n t e r f a c e
7 i n p u t N64_data ,
8 //VCR i n t e r f a c e
9 i n p u t vcr_data
10 );
11 logic data_VCR ;
12 logic data_n64 ;
13 logic data_button_board ;
14 logic [ 7 : 0 ] VCR_buttons ;
15
16 always_comb b e g i n
17 case ( controller_switch )
18 3 ’ b001 : data_to_NES = data_button_board ;
19 3 ’ b010 : data_to_NES = v c r _ d a t a ;
20 3 ’ b100 : data_to_NES = N64_data ;
21 d e f a u l t : data_to_NES = v c r _ d a t a ;
22 endcase
23 end
24
25 b u t t o n _ b o a r d _ c o n t r o l l e r button_board (
26 . c l k ( clk_nes ) ,
27 . latch ( latch_nes ) ,
28 . buttons ( buttons ) ,
29
30 . s o u t ( data_button_board )
31 );
32
33 b u t t o n _ b o a r d _ c o n t r o l l e r VCR_to_NES (
34 . c l k ( clk_nes ) ,
35 . latch ( latch_nes ) ,
36 . b u t t o n s ( VCR_buttons ) ,
37
38 . s o u t ( vcr_data )
39 );
40
41 OSCH #(" 2 . 0 8 " ) osc_int (
42
43 . STDBY( 1 ’ b0 ) , // S p e c i f i e s a c t i v e s t a t e
44 . OSC( c l k ) , // O u t p u t s c l o c k s i g n a l t o ’ clk ’ net
45 . SEDSTDBY ( ) ) ; // L e a v e s SEDSTDBY p i n u n c o n n e c t e d
46
47 // N64 c o n t r o l l e r
48 highest_level_n64 remote (
49 . clk_i ( clk ) ,
50 . reset_n (1) ,
51 . s o u t ( N64_data )
52 );
53
54 code_to_NES v c r (
55 . ir_in ( ir_in ) ,
56
57 . b u t t o n s ( VCR_buttons )
58 );
59
60
61
62
63
64 endmodule

B Simulation Files (Do scripts)


B.1 Button Board
1 vsim top
2 add wave c l k
3 add wave l a t c h
4 add wave b u t t o n s
5 add wave q
6 add wave s o u t
7 f o r c e c l k 0 0 , 1 50 −r 100
8 f o r c e l a t c h 1 0 , 0 20
9 f o r c e buttons 10101010
10 run 800

B.2 N64
1 #N64 Top s i m u l a t i o n
2 f o r c e r e s e t _ n 0 @ 0 ns , 1 @ 50 n s ;
3 f o r c e c l k _ i 0 @ 0 ns , 1 @ 2 5 0 n s −r e p e a t 500 ns ;
4 run 1000 us ;

1 #C l o c k _ s t e p p e r . s v s i m u l a t i o n
2 f o r c e clk_2MHZ 0 @ 0 , 1 @ 2 5 0 −r e p e a t 500 ns
3 f o r c e r e s e t _ n 0 @0 , 1 @ 10
4 run 1000000

17
1 #N64Reader . s v s i m u l a t i o n
2 f o r c e clk_1MHZ 0 @ 0 , 1 @ 5 0 0 n s −r e p e a t 1000 ns
3 f o r c e r e s e t _ n 0 @ 0 ns , 1 @ 50 n s
4 force state 0
5 run 1000000 ns

1 # l a t c h _ d e c i d e r . sv
2 f o r c e c l o c k 0 @ 0 , 1 @ 5 0 0 −r e p e a t 1 0 0 0
3 f o r c e r e s e t _ n 0 @ 0 , 1 @ 10
4 f o r c e s t a t e 1 @ 10 , 2 @ 300 , 0 @ 100000
5 run 1000000

1 # poll_read_SM . s v
2 f o r c e clk_4kHZ 0 @ 0 , 1 @ 1 2 5 −r e p e a t 250
3 f o r c e r e s e t _ n 0 @ 0 , 1 @ 10
4
5 run 1000000

1 #c o n t r o l l e r _ a r r a y _ c y c l e r
2
3 force clk_4kHZ 0 @ 0 , 1 @ 1 2 5 −r e p e a t 2 5 0
4 force r e s e t _ n 0 @ 0 , 1 @ 10
5 force i s _ i d l e 0 @ 0 , 2 @ 5 0 0 −r e p e a t 1 0 0 0
6
7 run 100000

1 #s h i f t _ r e g i s t e r . do
2 f o r c e clk_1MHZ 0 @ 0 , 1 @ 5 0 0 −r e p e a t 1 0 0 0
3 f o r c e r e s e t _ n 0 @ 0 , 1 @ 10
4 force state 1
5 f o r c e bit_array 2#11000000000000000000000000000000
6 run 1000000

B.3 VCR Remote


1 v s i m code_to_NES
2
3 add wave c o d e
4 add wave b u t t o n s
5
6 force code 10011100011000111000000001111111 @ 0 , 10011100011000110010000011011111 @ 100 ,
10011100011000111010000001011111 @ 200 , 10011100011000110110000010011111 @ 300 ,
10011100011000111110100000010111 @ 400 , 10011100011000110001100011100111 @ 500 ,
10011100011000111001000001101111 @ 600 , 10011100011000110101000010101111 @ 700 ,
10011100011000110101001010101101 @ 8 0 0 , 10011100011000110110001010011101 @ 900
7
8 run 1000

1 v s i m compare
2 add wave p
3 add wave q
4 add wave s i g n a l
5
6 force p 101110111000 @ 100 , 001111101000 @ 200
7 force q 011111010000 @ 100
8
9 run 300

1 vsim compare_to_parallel_shift
2
3 add wave s _ i n
4 add wave c l k
5 add wave c o d e
6
7 force c l k 0 @ 0 , 1 @ 1 0 0 −r 200
8 force s_in 0 @ 0 , 1 @ 600
9
10 run 1200

1 vsim c o u n t e r
2 add wave c l k
3 add wave r e s e t
4 add wave r e s u l t
5
6 force c l k 0 @ 100 , 1 @ 200 , 0 @ 300 , 1 @ 400 , 0 @ 500 , 1 @ 600
7 force r e s e t 1 @ 1 0 0 , 0 @ 3 0 0 , 1 @ 500
8
9 run 800

18

Potrebbero piacerti anche