Subversion Repositories pentevo

Rev

Rev 543 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
668 lvd 1
// ZX-Evo Base Configuration (c) NedoPC 2008,2009,2010,2011,2012,2013,2014
67 lvd 2
//
543 lvd 3
// fpga SPI slave device -- AVR controlled.
67 lvd 4
 
668 lvd 5
/*
6
    This file is part of ZX-Evo Base Configuration firmware.
67 lvd 7
 
668 lvd 8
    ZX-Evo Base Configuration firmware is free software:
9
    you can redistribute it and/or modify it under the terms of
10
    the GNU General Public License as published by
11
    the Free Software Foundation, either version 3 of the License, or
12
    (at your option) any later version.
543 lvd 13
 
668 lvd 14
    ZX-Evo Base Configuration firmware is distributed in the hope that
15
    it will be useful, but WITHOUT ANY WARRANTY; without even
16
    the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
    See the GNU General Public License for more details.
543 lvd 18
 
668 lvd 19
    You should have received a copy of the GNU General Public License
20
    along with ZX-Evo Base Configuration firmware.
21
    If not, see <http://www.gnu.org/licenses/>.
22
*/
23
 
30 lvd 24
`include "../include/tune.v"
25
 
4 lvd 26
module slavespi(
27
 
67 lvd 28
        input  wire fclk,
29
        input  wire rst_n,
4 lvd 30
 
67 lvd 31
        input  wire spics_n, // avr SPI iface
32
        output wire spidi,   //
33
        input  wire spido,   //
34
        input  wire spick,   //
4 lvd 35
 
67 lvd 36
        input  wire [ 7:0] status_in, // status bits to be shown to avr
4 lvd 37
 
38
 
67 lvd 39
        output wire [39:0] kbd_out,
40
        output wire        kbd_stb,
4 lvd 41
 
67 lvd 42
        output wire [ 7:0] mus_out,
43
        output wire        mus_xstb,
44
        output wire        mus_ystb,
45
        output wire        mus_btnstb,
110 lvd 46
        output wire        kj_stb,
67 lvd 47
 
48
 
88 lvd 49
        input  wire [ 7:0] gluclock_addr,
228 lvd 50
        input  wire [ 2:0] comport_addr,
88 lvd 51
 
52
        input  wire [ 7:0] wait_write,
53
        output wire [ 7:0] wait_read,
54
        input  wire        wait_rnw,
55
 
56
        output wire        wait_end,
57
 
98 lvd 58
        output wire [ 7:0] config0, // config bits for overall system
59
 
543 lvd 60
        output wire        genrst, // positive pulse, causes Z80 reset
61
 
62
        output wire        sd_lock_out, // SDcard control iface
63
        input  wire        sd_lock_in,  //
64
        output wire        sd_cs_n,     //
65
        output wire        sd_start,    //
66
        output wire [ 7:0] sd_datain,   //
67
        input  wire [ 7:0] sd_dataout   //
4 lvd 68
);
69
 
200 lvd 70
`ifdef SIMULATE
71
        initial
72
        begin
425 lvd 73
                force wait_read = 8'h00;
200 lvd 74
        end
75
`endif
76
 
77
 
67 lvd 78
        // re-synchronize SPI
79
        //
80
        reg [2:0] spics_n_sync;
81
        reg [1:0] spido_sync;
82
        reg [2:0] spick_sync;
83
        //
84
        always @(posedge fclk)
85
        begin
86
                spics_n_sync[2:0] <= { spics_n_sync[1:0], spics_n };
87
                spido_sync  [1:0] <= { spido_sync    [0], spido   };
88
                spick_sync  [2:0] <= { spick_sync  [1:0], spick   };
89
        end
90
        //
91
        wire scs_n = spics_n_sync[1]; // scs_n - synchronized CS_N
92
        wire sdo   = spido_sync[1];
93
        wire sck   = spick_sync[1];
94
        //
95
        wire scs_n_01 = (~spics_n_sync[2]) &   spics_n_sync[1] ;
96
        wire scs_n_10 =   spics_n_sync[2]  & (~spics_n_sync[1]);
97
        //
88 lvd 98
        wire sck_01 = (~spick_sync[2]) &   spick_sync[1] ;
99
        wire sck_10 =   spick_sync[2]  & (~spick_sync[1]);
4 lvd 100
 
40 lvd 101
 
67 lvd 102
        reg [7:0] regnum; // register number holder
103
 
104
        reg [7:0] shift_out;
105
 
88 lvd 106
        reg [7:0] data_in;
67 lvd 107
 
108
 
109
 
110
        // register selectors
543 lvd 111
        wire sel_kbdreg, sel_kbdstb, sel_musxcr, sel_musycr, sel_musbtn, sel_kj,
112
             sel_rstreg, sel_waitreg, sel_gluadr, sel_comadr, sel_cfg0,
113
             sel_sddata, sel_sdctrl;
67 lvd 114
 
115
        // keyboard register
116
        reg [39:0] kbd_reg;
117
 
118
 
543 lvd 119
        // common single-byte shift-in register
120
        reg [7:0] common_reg;
67 lvd 121
 
543 lvd 122
 
88 lvd 123
        // wait data out register
124
        reg [7:0] wait_reg;
67 lvd 125
 
98 lvd 126
        //
543 lvd 127
        reg [7:0] cfg0_reg_out; // one for shifting, second for storing values
67 lvd 128
 
129
 
543 lvd 130
        // SDcard access registers
131
        reg [7:0] sddata; // output to SDcard
132
        reg [1:0] sdctrl; // SDcard control (CS_n and lock)
67 lvd 133
 
543 lvd 134
 
40 lvd 135
`ifdef SIMULATE
136
        initial
137
        begin
200 lvd 138
                cfg0_reg_out[7:0] = 8'd0;
40 lvd 139
        end
140
`endif
141
 
142
 
67 lvd 143
        // register number
144
        //
145
        always @(posedge fclk)
146
        begin
147
                if( scs_n_01 )
148
                begin
149
                        regnum <= 8'd0;
150
                end
69 lvd 151
                else if( scs_n && sck_01 )
67 lvd 152
                begin
153
                        regnum[7:0] <= { sdo, regnum[7:1] };
154
                end
155
        end
40 lvd 156
 
157
 
67 lvd 158
        // send data to avr
159
        //
88 lvd 160
        always @*
543 lvd 161
        case(1'b1)
162
                sel_waitreg: data_in = wait_write;
163
                sel_gluadr:  data_in = gluclock_addr;
164
                sel_comadr:  data_in = comport_addr;
165
                sel_sddata:  data_in = sd_dataout;
166
                sel_sdctrl:  data_in = { sd_lock_in, 7'bXXX_XXXX };
167
                default:     data_in = 8'bXXXX_XXXX;
168
        endcase
88 lvd 169
        //
67 lvd 170
        always @(posedge fclk)
171
        begin
172
                if( scs_n_01 || scs_n_10 ) // both edges
173
                begin
174
                        shift_out <= scs_n ? status_in : data_in;
175
                end
176
                else if( sck_01 )
177
                begin
178
                        shift_out[7:0] <= { 1'b0, shift_out[7:1] };
179
                end
180
        end
181
        //
182
        assign spidi = shift_out[0];
183
 
184
 
185
        // reg number decoding
186
        //
110 lvd 187
        assign sel_kbdreg = ( (regnum[7:4]==4'h1) && !regnum[0] ); // $10
188
        assign sel_kbdstb = ( (regnum[7:4]==4'h1) &&  regnum[0] ); // $11
67 lvd 189
        //
110 lvd 190
        assign sel_musxcr = ( (regnum[7:4]==4'h2) && !regnum[1] && !regnum[0] ); // $20
191
        assign sel_musycr = ( (regnum[7:4]==4'h2) && !regnum[1] &&  regnum[0] ); // $21
192
        assign sel_musbtn = ( (regnum[7:4]==4'h2) &&  regnum[1] && !regnum[0] ); // $22
193
        assign sel_kj     = ( (regnum[7:4]==4'h2) &&  regnum[1] &&  regnum[0] ); // $23
67 lvd 194
        //
110 lvd 195
        assign sel_rstreg = ( (regnum[7:4]==4'h3) ) ; // $30
88 lvd 196
        //
228 lvd 197
        assign sel_waitreg = ( (regnum[7:4]==4'h4) && (regnum[1:0]==2'b00) ); // $40
198
        assign sel_gluadr  = ( (regnum[7:4]==4'h4) && (regnum[1:0]==2'b01) ); // $41
199
        assign sel_comadr  = ( (regnum[7:4]==4'h4) && (regnum[1:0]==2'b10) ); // $42
98 lvd 200
        //
110 lvd 201
        assign sel_cfg0 = (regnum[7:4]==4'h5); // $50
543 lvd 202
        //
203
        assign sel_sddata = ( (regnum[7:4]==4'h6) && !regnum[0] ); // $60
204
        assign sel_sdctrl = ( (regnum[7:4]==4'h6) &&  regnum[0] ); // $61
67 lvd 205
 
206
 
207
        // registers data-in
208
        //
209
        always @(posedge fclk)
210
        begin
543 lvd 211
                // kbd data shift-in
70 lvd 212
                if( !scs_n && sel_kbdreg && sck_01 )
67 lvd 213
                        kbd_reg[39:0] <= { sdo, kbd_reg[39:1] };
214
 
543 lvd 215
                // mouse data shift-in
110 lvd 216
                if( !scs_n && (sel_musxcr || sel_musycr || sel_musbtn || sel_kj) && sck_01 )
543 lvd 217
                        common_reg[7:0] <= { sdo, common_reg[7:1] };
67 lvd 218
 
543 lvd 219
                // wait read data shift-in
88 lvd 220
                if( !scs_n && sel_waitreg && sck_01 )
221
                        wait_reg[7:0] <= { sdo, wait_reg[7:1] };
98 lvd 222
 
543 lvd 223
                // config shift-in
98 lvd 224
                if( !scs_n && sel_cfg0 && sck_01 )
543 lvd 225
                        common_reg[7:0] <= { sdo, common_reg[7:1] };
98 lvd 226
 
543 lvd 227
                // config output
98 lvd 228
                if( scs_n_01 && sel_cfg0 )
543 lvd 229
                        cfg0_reg_out <= common_reg;
230
 
231
                // SD data shift-in
232
                if( !scs_n && sel_sddata && sck_01 )
233
                        common_reg[7:0] <= { sdo, common_reg[7:1] };
234
 
235
                // SD control shift-in
236
                if( !scs_n && sel_sdctrl && sck_01 )
237
                        common_reg[7:0] <= { sdo, common_reg[7:1] };
67 lvd 238
        end
543 lvd 239
        //
240
        // SD control output
241
        always @(posedge fclk, negedge rst_n)
242
        if( !rst_n )
243
                sdctrl <= 2'b01;
244
        else // posedge clk
245
        begin
246
                if( scs_n_01 && sel_sdctrl )
247
                        sdctrl <= { common_reg[7], common_reg[0] };
248
        end
67 lvd 249
 
250
 
251
        // output data
252
        assign kbd_out = kbd_reg;
70 lvd 253
        assign kbd_stb = sel_kbdstb && scs_n_01;
67 lvd 254
 
543 lvd 255
        assign mus_out    = common_reg;
67 lvd 256
        assign mus_xstb   = sel_musxcr && scs_n_01;
257
        assign mus_ystb   = sel_musycr && scs_n_01;
258
        assign mus_btnstb = sel_musbtn && scs_n_01;
110 lvd 259
        assign kj_stb     = sel_kj     && scs_n_01;
67 lvd 260
 
261
        assign genrst = sel_rstreg && scs_n_01;
262
 
88 lvd 263
        assign wait_read = wait_reg;
264
        assign wait_end = sel_waitreg && scs_n_01;
4 lvd 265
 
98 lvd 266
        assign config0 = cfg0_reg_out;
4 lvd 267
 
543 lvd 268
 
269
 
270
        // SD control output
271
        assign sd_lock_out = sdctrl[1];
272
        assign sd_cs_n     = sdctrl[0];
273
 
274
        // SD data output
275
        assign sd_datain = common_reg;
276
        // SD start strobe
277
        assign sd_start = sel_sddata && scs_n_01;
278
 
279
 
4 lvd 280
endmodule
281