Subversion Repositories pentevo

Rev

Rev 668 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
826 lvd 1
// ZX-Evo Base Configuration (c) NedoPC 2008,2009,2010,2011,2012,2013,2014,2019
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
826 lvd 59
        output wire [ 7:0] config1, //
98 lvd 60
 
543 lvd 61
        output wire        genrst, // positive pulse, causes Z80 reset
62
 
63
        output wire        sd_lock_out, // SDcard control iface
64
        input  wire        sd_lock_in,  //
65
        output wire        sd_cs_n,     //
66
        output wire        sd_start,    //
67
        output wire [ 7:0] sd_datain,   //
68
        input  wire [ 7:0] sd_dataout   //
4 lvd 69
);
70
 
200 lvd 71
`ifdef SIMULATE
72
        initial
73
        begin
425 lvd 74
                force wait_read = 8'h00;
200 lvd 75
        end
76
`endif
77
 
78
 
67 lvd 79
        // re-synchronize SPI
80
        //
81
        reg [2:0] spics_n_sync;
82
        reg [1:0] spido_sync;
83
        reg [2:0] spick_sync;
84
        //
85
        always @(posedge fclk)
86
        begin
87
                spics_n_sync[2:0] <= { spics_n_sync[1:0], spics_n };
88
                spido_sync  [1:0] <= { spido_sync    [0], spido   };
89
                spick_sync  [2:0] <= { spick_sync  [1:0], spick   };
90
        end
91
        //
92
        wire scs_n = spics_n_sync[1]; // scs_n - synchronized CS_N
93
        wire sdo   = spido_sync[1];
94
        wire sck   = spick_sync[1];
95
        //
96
        wire scs_n_01 = (~spics_n_sync[2]) &   spics_n_sync[1] ;
97
        wire scs_n_10 =   spics_n_sync[2]  & (~spics_n_sync[1]);
98
        //
88 lvd 99
        wire sck_01 = (~spick_sync[2]) &   spick_sync[1] ;
100
        wire sck_10 =   spick_sync[2]  & (~spick_sync[1]);
4 lvd 101
 
40 lvd 102
 
67 lvd 103
        reg [7:0] regnum; // register number holder
104
 
105
        reg [7:0] shift_out;
106
 
88 lvd 107
        reg [7:0] data_in;
67 lvd 108
 
109
 
110
 
111
        // register selectors
543 lvd 112
        wire sel_kbdreg, sel_kbdstb, sel_musxcr, sel_musycr, sel_musbtn, sel_kj,
826 lvd 113
             sel_rstreg, sel_waitreg, sel_gluadr, sel_comadr, sel_cfg0, sel_cfg1,
543 lvd 114
             sel_sddata, sel_sdctrl;
67 lvd 115
 
116
        // keyboard register
117
        reg [39:0] kbd_reg;
118
 
119
 
543 lvd 120
        // common single-byte shift-in register
121
        reg [7:0] common_reg;
67 lvd 122
 
543 lvd 123
 
88 lvd 124
        // wait data out register
125
        reg [7:0] wait_reg;
67 lvd 126
 
98 lvd 127
        //
826 lvd 128
        reg [7:0] cfg0_reg_out;
129
        reg [7:0] cfg1_reg_out;
67 lvd 130
 
131
 
543 lvd 132
        // SDcard access registers
133
        reg [7:0] sddata; // output to SDcard
134
        reg [1:0] sdctrl; // SDcard control (CS_n and lock)
67 lvd 135
 
543 lvd 136
 
40 lvd 137
`ifdef SIMULATE
138
        initial
139
        begin
200 lvd 140
                cfg0_reg_out[7:0] = 8'd0;
40 lvd 141
        end
142
`endif
143
 
144
 
67 lvd 145
        // register number
146
        //
147
        always @(posedge fclk)
148
        begin
149
                if( scs_n_01 )
150
                begin
151
                        regnum <= 8'd0;
152
                end
69 lvd 153
                else if( scs_n && sck_01 )
67 lvd 154
                begin
155
                        regnum[7:0] <= { sdo, regnum[7:1] };
156
                end
157
        end
40 lvd 158
 
159
 
67 lvd 160
        // send data to avr
161
        //
88 lvd 162
        always @*
543 lvd 163
        case(1'b1)
164
                sel_waitreg: data_in = wait_write;
165
                sel_gluadr:  data_in = gluclock_addr;
166
                sel_comadr:  data_in = comport_addr;
167
                sel_sddata:  data_in = sd_dataout;
168
                sel_sdctrl:  data_in = { sd_lock_in, 7'bXXX_XXXX };
169
                default:     data_in = 8'bXXXX_XXXX;
170
        endcase
88 lvd 171
        //
67 lvd 172
        always @(posedge fclk)
173
        begin
174
                if( scs_n_01 || scs_n_10 ) // both edges
175
                begin
176
                        shift_out <= scs_n ? status_in : data_in;
177
                end
178
                else if( sck_01 )
179
                begin
180
                        shift_out[7:0] <= { 1'b0, shift_out[7:1] };
181
                end
182
        end
183
        //
184
        assign spidi = shift_out[0];
185
 
186
 
187
        // reg number decoding
188
        //
110 lvd 189
        assign sel_kbdreg = ( (regnum[7:4]==4'h1) && !regnum[0] ); // $10
190
        assign sel_kbdstb = ( (regnum[7:4]==4'h1) &&  regnum[0] ); // $11
67 lvd 191
        //
110 lvd 192
        assign sel_musxcr = ( (regnum[7:4]==4'h2) && !regnum[1] && !regnum[0] ); // $20
193
        assign sel_musycr = ( (regnum[7:4]==4'h2) && !regnum[1] &&  regnum[0] ); // $21
194
        assign sel_musbtn = ( (regnum[7:4]==4'h2) &&  regnum[1] && !regnum[0] ); // $22
195
        assign sel_kj     = ( (regnum[7:4]==4'h2) &&  regnum[1] &&  regnum[0] ); // $23
67 lvd 196
        //
110 lvd 197
        assign sel_rstreg = ( (regnum[7:4]==4'h3) ) ; // $30
88 lvd 198
        //
228 lvd 199
        assign sel_waitreg = ( (regnum[7:4]==4'h4) && (regnum[1:0]==2'b00) ); // $40
200
        assign sel_gluadr  = ( (regnum[7:4]==4'h4) && (regnum[1:0]==2'b01) ); // $41
201
        assign sel_comadr  = ( (regnum[7:4]==4'h4) && (regnum[1:0]==2'b10) ); // $42
98 lvd 202
        //
826 lvd 203
        assign sel_cfg0 = (regnum[7:4]==4'h5 && regnum[0]==1'b0); // $50
204
        assign sel_cfg1 = (regnum[7:4]==4'h5 && regnum[0]==1'b1); // $51
543 lvd 205
        //
206
        assign sel_sddata = ( (regnum[7:4]==4'h6) && !regnum[0] ); // $60
207
        assign sel_sdctrl = ( (regnum[7:4]==4'h6) &&  regnum[0] ); // $61
67 lvd 208
 
209
 
210
        // registers data-in
211
        //
212
        always @(posedge fclk)
213
        begin
543 lvd 214
                // kbd data shift-in
70 lvd 215
                if( !scs_n && sel_kbdreg && sck_01 )
67 lvd 216
                        kbd_reg[39:0] <= { sdo, kbd_reg[39:1] };
217
 
543 lvd 218
                // mouse data shift-in
110 lvd 219
                if( !scs_n && (sel_musxcr || sel_musycr || sel_musbtn || sel_kj) && sck_01 )
543 lvd 220
                        common_reg[7:0] <= { sdo, common_reg[7:1] };
67 lvd 221
 
543 lvd 222
                // wait read data shift-in
88 lvd 223
                if( !scs_n && sel_waitreg && sck_01 )
224
                        wait_reg[7:0] <= { sdo, wait_reg[7:1] };
98 lvd 225
 
543 lvd 226
                // config shift-in
826 lvd 227
                if( !scs_n && (sel_cfg0 || sel_cfg1) && sck_01 )
543 lvd 228
                        common_reg[7:0] <= { sdo, common_reg[7:1] };
98 lvd 229
 
543 lvd 230
                // config output
98 lvd 231
                if( scs_n_01 && sel_cfg0 )
543 lvd 232
                        cfg0_reg_out <= common_reg;
826 lvd 233
                if( scs_n_01 && sel_cfg1 )
234
                        cfg1_reg_out <= common_reg;
543 lvd 235
 
236
                // SD data shift-in
237
                if( !scs_n && sel_sddata && sck_01 )
238
                        common_reg[7:0] <= { sdo, common_reg[7:1] };
239
 
240
                // SD control shift-in
241
                if( !scs_n && sel_sdctrl && sck_01 )
242
                        common_reg[7:0] <= { sdo, common_reg[7:1] };
67 lvd 243
        end
543 lvd 244
        //
245
        // SD control output
246
        always @(posedge fclk, negedge rst_n)
247
        if( !rst_n )
248
                sdctrl <= 2'b01;
249
        else // posedge clk
250
        begin
251
                if( scs_n_01 && sel_sdctrl )
252
                        sdctrl <= { common_reg[7], common_reg[0] };
253
        end
67 lvd 254
 
255
 
256
        // output data
257
        assign kbd_out = kbd_reg;
70 lvd 258
        assign kbd_stb = sel_kbdstb && scs_n_01;
67 lvd 259
 
543 lvd 260
        assign mus_out    = common_reg;
67 lvd 261
        assign mus_xstb   = sel_musxcr && scs_n_01;
262
        assign mus_ystb   = sel_musycr && scs_n_01;
263
        assign mus_btnstb = sel_musbtn && scs_n_01;
110 lvd 264
        assign kj_stb     = sel_kj     && scs_n_01;
67 lvd 265
 
266
        assign genrst = sel_rstreg && scs_n_01;
267
 
88 lvd 268
        assign wait_read = wait_reg;
269
        assign wait_end = sel_waitreg && scs_n_01;
4 lvd 270
 
98 lvd 271
        assign config0 = cfg0_reg_out;
826 lvd 272
        assign config1 = cfg1_reg_out;
4 lvd 273
 
543 lvd 274
 
275
 
276
        // SD control output
277
        assign sd_lock_out = sdctrl[1];
278
        assign sd_cs_n     = sdctrl[0];
279
 
280
        // SD data output
281
        assign sd_datain = common_reg;
282
        // SD start strobe
283
        assign sd_start = sel_sddata && scs_n_01;
284
 
285
 
4 lvd 286
endmodule
287