Subversion Repositories pentevo

Rev

Rev 543 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. // ZX-Evo Base Configuration (c) NedoPC 2008,2009,2010,2011,2012,2013,2014
  2. //
  3. // fpga SPI slave device -- AVR controlled.
  4.  
  5. /*
  6.     This file is part of ZX-Evo Base Configuration firmware.
  7.  
  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.
  13.  
  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.
  18.  
  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.  
  24. `include "../include/tune.v"
  25.  
  26. module slavespi(
  27.  
  28.         input  wire fclk,
  29.         input  wire rst_n,
  30.  
  31.         input  wire spics_n, // avr SPI iface
  32.         output wire spidi,   //
  33.         input  wire spido,   //
  34.         input  wire spick,   //
  35.  
  36.         input  wire [ 7:0] status_in, // status bits to be shown to avr
  37.  
  38.  
  39.         output wire [39:0] kbd_out,
  40.         output wire        kbd_stb,
  41.  
  42.         output wire [ 7:0] mus_out,
  43.         output wire        mus_xstb,
  44.         output wire        mus_ystb,
  45.         output wire        mus_btnstb,
  46.         output wire        kj_stb,
  47.  
  48.  
  49.         input  wire [ 7:0] gluclock_addr,
  50.         input  wire [ 2:0] comport_addr,
  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.  
  58.         output wire [ 7:0] config0, // config bits for overall system
  59.  
  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   //
  68. );
  69.  
  70. `ifdef SIMULATE
  71.         initial
  72.         begin
  73.                 force wait_read = 8'h00;
  74.         end
  75. `endif
  76.  
  77.  
  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.         //
  98.         wire sck_01 = (~spick_sync[2]) &   spick_sync[1] ;
  99.         wire sck_10 =   spick_sync[2]  & (~spick_sync[1]);
  100.  
  101.  
  102.         reg [7:0] regnum; // register number holder
  103.  
  104.         reg [7:0] shift_out;
  105.  
  106.         reg [7:0] data_in;
  107.  
  108.  
  109.  
  110.         // register selectors
  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;
  114.  
  115.         // keyboard register
  116.         reg [39:0] kbd_reg;
  117.  
  118.  
  119.         // common single-byte shift-in register
  120.         reg [7:0] common_reg;
  121.  
  122.  
  123.         // wait data out register
  124.         reg [7:0] wait_reg;
  125.  
  126.         //
  127.         reg [7:0] cfg0_reg_out; // one for shifting, second for storing values
  128.  
  129.  
  130.         // SDcard access registers
  131.         reg [7:0] sddata; // output to SDcard
  132.         reg [1:0] sdctrl; // SDcard control (CS_n and lock)
  133.  
  134.  
  135. `ifdef SIMULATE
  136.         initial
  137.         begin
  138.                 cfg0_reg_out[7:0] = 8'd0;
  139.         end
  140. `endif
  141.  
  142.  
  143.         // register number
  144.         //
  145.         always @(posedge fclk)
  146.         begin
  147.                 if( scs_n_01 )
  148.                 begin
  149.                         regnum <= 8'd0;
  150.                 end
  151.                 else if( scs_n && sck_01 )
  152.                 begin
  153.                         regnum[7:0] <= { sdo, regnum[7:1] };
  154.                 end
  155.         end
  156.  
  157.  
  158.         // send data to avr
  159.         //
  160.         always @*
  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
  169.         //
  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.         //
  187.         assign sel_kbdreg = ( (regnum[7:4]==4'h1) && !regnum[0] ); // $10
  188.         assign sel_kbdstb = ( (regnum[7:4]==4'h1) &&  regnum[0] ); // $11
  189.         //
  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
  194.         //
  195.         assign sel_rstreg = ( (regnum[7:4]==4'h3) ) ; // $30
  196.         //
  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
  200.         //
  201.         assign sel_cfg0 = (regnum[7:4]==4'h5); // $50
  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
  205.  
  206.  
  207.         // registers data-in
  208.         //
  209.         always @(posedge fclk)
  210.         begin
  211.                 // kbd data shift-in
  212.                 if( !scs_n && sel_kbdreg && sck_01 )
  213.                         kbd_reg[39:0] <= { sdo, kbd_reg[39:1] };
  214.  
  215.                 // mouse data shift-in
  216.                 if( !scs_n && (sel_musxcr || sel_musycr || sel_musbtn || sel_kj) && sck_01 )
  217.                         common_reg[7:0] <= { sdo, common_reg[7:1] };
  218.  
  219.                 // wait read data shift-in
  220.                 if( !scs_n && sel_waitreg && sck_01 )
  221.                         wait_reg[7:0] <= { sdo, wait_reg[7:1] };
  222.  
  223.                 // config shift-in
  224.                 if( !scs_n && sel_cfg0 && sck_01 )
  225.                         common_reg[7:0] <= { sdo, common_reg[7:1] };
  226.  
  227.                 // config output
  228.                 if( scs_n_01 && sel_cfg0 )
  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] };
  238.         end
  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
  249.  
  250.  
  251.         // output data
  252.         assign kbd_out = kbd_reg;
  253.         assign kbd_stb = sel_kbdstb && scs_n_01;
  254.  
  255.         assign mus_out    = common_reg;
  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;
  259.         assign kj_stb     = sel_kj     && scs_n_01;
  260.  
  261.         assign genrst = sel_rstreg && scs_n_01;
  262.  
  263.         assign wait_read = wait_reg;
  264.         assign wait_end = sel_waitreg && scs_n_01;
  265.  
  266.         assign config0 = cfg0_reg_out;
  267.  
  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.  
  280. endmodule
  281.  
  282.