OpenCores
URL https://opencores.org/ocsvn/nescontroller/nescontroller/trunk

Subversion Repositories nescontroller

[/] [nescontroller/] [trunk/] [nescontroller.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 yzoer
/*
2
 * This IP is a 'classic' Nintendo NES serial -> parallel converter
3
 *
4
 * Copyright (C) 2019, Yvo Zoer
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19
 */
20
 
21
module nescontroller (
22
        clk,
23
        reset_n,
24
        frame,
25
        nes_latch,
26
        nes_clk,
27
        nes_data0,
28
        nes_data1,
29
        q0,
30
        q1,
31
        busy
32
        );
33
 
34
        input clk;
35
        input reset_n;
36
        input frame;
37
        output nes_latch;
38
        output nes_clk;
39
        input nes_data0, nes_data1;
40
        output [7:0] q0, q1;
41
        output busy = (frame != STATE_IDLE);
42
 
43
        // states for state-machine
44
        parameter STATE_IDLE            = 3'd0;
45
        parameter STATE_LATCH_HI        = 3'd1;
46
        parameter STATE_LATCH_LO        = 3'd2;
47
        parameter STATE_CLOCK_LO        = 3'd3;
48
        parameter STATE_CLOCK_HI        = 3'd4;
49
        parameter STATE_DONE            = 3'd5;
50
 
51
        // start bit to catch single clock frame event
52
        reg start;
53
        always @(posedge clk or negedge reset_n)
54
                if (!reset_n)
55
                        start <= 1'b0;
56
                else if ( frame )
57
                        start <= 1'b1;
58
                else if ( state != STATE_IDLE )
59
                        start <= 1'b0;
60
 
61
        // clock divider / enable -- clock needs to be around 1.5mhz or lower
62
        reg [3:0] clkdiv;
63
        always @(posedge clk or negedge reset_n)
64
                if (!reset_n)
65
                        clkdiv <= 4'd0;
66
                else
67
                        clkdiv <= clkdiv + 4'd1;
68
 
69
        wire enable = &clkdiv;
70
 
71
        // main state machine
72
        reg [3:0] state, next_state;
73
        always @(*)
74
                case (state)
75
                        STATE_IDLE : begin
76
                                if ( start )
77
                                        next_state = STATE_LATCH_HI;
78
                                else
79
                                        next_state = STATE_IDLE;
80
                                end
81
                        STATE_LATCH_HI : next_state = STATE_LATCH_LO;
82
                        STATE_LATCH_LO : next_state = STATE_CLOCK_LO;
83
                        STATE_CLOCK_LO : next_state = STATE_CLOCK_HI;
84
                        STATE_CLOCK_HI : begin
85
                                if ( &count )
86
                                        next_state = STATE_DONE;
87
                                else
88
                                        next_state = STATE_CLOCK_LO;
89
                                end
90
                        default : begin
91
                                next_state = STATE_IDLE;
92
                                end
93
                endcase
94
 
95
        reg nes_latch;
96
        always @(posedge clk or negedge reset_n)
97
                if (!reset_n)
98
                        nes_latch <= 1'b0;
99
                else
100
                        nes_latch <= (state == STATE_LATCH_HI);
101
 
102
        reg nes_clk;
103
        always @(posedge clk or negedge reset_n)
104
                if (!reset_n)
105
                        nes_clk <= 1'b1;
106
                else
107
                        nes_clk = (state == STATE_CLOCK_LO ) ? 1'b0 : 1'b1;
108
 
109
        reg [2:0] count, next_count;
110
        always @(*)
111
                if ( state == STATE_CLOCK_HI )
112
                        next_count = count + 3'd1;
113
                else
114
                        next_count = count;
115
 
116
        reg [7:0] q0, next_q0;
117
        reg [7:0] q1, next_q1;
118
        always @(*)
119
                if ( state == STATE_CLOCK_LO )
120
                        begin
121
                                next_q0 = { q0[6:0], nes_data1 };                // reversed due to board layout
122
                                next_q1 = { q1[6:0], nes_data0 };
123
                        end
124
                else
125
                        begin
126
                                next_q0 = q0;
127
                                next_q1 = q1;
128
                        end
129
 
130
        always @(posedge clk or negedge reset_n )
131
                if (!reset_n)
132
                        begin
133
                                state <= STATE_IDLE;
134
                                count <= 3'd0;
135
                                q0 <= 8'h00;
136
                                q1 <= 8'h00;
137
                        end
138
                else if ( enable )
139
                        begin
140
                                state <= next_state;
141
                                count <= next_count;
142
                                q0 <= next_q0;
143
                                q1 <= next_q1;
144
                        end
145
 
146
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.