Subversion Repositories pentevo

Rev

Rev 668 | 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,2019
  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.         output wire [ 7:0] config1, //
  60.  
  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   //
  69. );
  70.  
  71. `ifdef SIMULATE
  72.         initial
  73.         begin
  74.                 force wait_read = 8'h00;
  75.         end
  76. `endif
  77.  
  78.  
  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.         //
  99.         wire sck_01 = (~spick_sync[2]) &   spick_sync[1] ;
  100.         wire sck_10 =   spick_sync[2]  & (~spick_sync[1]);
  101.  
  102.  
  103.         reg [7:0] regnum; // register number holder
  104.  
  105.         reg [7:0] shift_out;
  106.  
  107.         reg [7:0] data_in;
  108.  
  109.  
  110.  
  111.         // register selectors
  112.         wire sel_kbdreg, sel_kbdstb, sel_musxcr, sel_musycr, sel_musbtn, sel_kj,
  113.              sel_rstreg, sel_waitreg, sel_gluadr, sel_comadr, sel_cfg0, sel_cfg1,
  114.              sel_sddata, sel_sdctrl;
  115.  
  116.         // keyboard register
  117.         reg [39:0] kbd_reg;
  118.  
  119.  
  120.         // common single-byte shift-in register
  121.         reg [7:0] common_reg;
  122.  
  123.  
  124.         // wait data out register
  125.         reg [7:0] wait_reg;
  126.  
  127.         //
  128.         reg [7:0] cfg0_reg_out;
  129.         reg [7:0] cfg1_reg_out;
  130.  
  131.  
  132.         // SDcard access registers
  133.         reg [7:0] sddata; // output to SDcard
  134.         reg [1:0] sdctrl; // SDcard control (CS_n and lock)
  135.  
  136.  
  137. `ifdef SIMULATE
  138.         initial
  139.         begin
  140.                 cfg0_reg_out[7:0] = 8'd0;
  141.         end
  142. `endif
  143.  
  144.  
  145.         // register number
  146.         //
  147.         always @(posedge fclk)
  148.         begin
  149.                 if( scs_n_01 )
  150.                 begin
  151.                         regnum <= 8'd0;
  152.                 end
  153.                 else if( scs_n && sck_01 )
  154.                 begin
  155.                         regnum[7:0] <= { sdo, regnum[7:1] };
  156.                 end
  157.         end
  158.  
  159.  
  160.         // send data to avr
  161.         //
  162.         always @*
  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
  171.         //
  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.         //
  189.         assign sel_kbdreg = ( (regnum[7:4]==4'h1) && !regnum[0] ); // $10
  190.         assign sel_kbdstb = ( (regnum[7:4]==4'h1) &&  regnum[0] ); // $11
  191.         //
  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
  196.         //
  197.         assign sel_rstreg = ( (regnum[7:4]==4'h3) ) ; // $30
  198.         //
  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
  202.         //
  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
  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
  208.  
  209.  
  210.         // registers data-in
  211.         //
  212.         always @(posedge fclk)
  213.         begin
  214.                 // kbd data shift-in
  215.                 if( !scs_n && sel_kbdreg && sck_01 )
  216.                         kbd_reg[39:0] <= { sdo, kbd_reg[39:1] };
  217.  
  218.                 // mouse data shift-in
  219.                 if( !scs_n && (sel_musxcr || sel_musycr || sel_musbtn || sel_kj) && sck_01 )
  220.                         common_reg[7:0] <= { sdo, common_reg[7:1] };
  221.  
  222.                 // wait read data shift-in
  223.                 if( !scs_n && sel_waitreg && sck_01 )
  224.                         wait_reg[7:0] <= { sdo, wait_reg[7:1] };
  225.  
  226.                 // config shift-in
  227.                 if( !scs_n && (sel_cfg0 || sel_cfg1) && sck_01 )
  228.                         common_reg[7:0] <= { sdo, common_reg[7:1] };
  229.  
  230.                 // config output
  231.                 if( scs_n_01 && sel_cfg0 )
  232.                         cfg0_reg_out <= common_reg;
  233.                 if( scs_n_01 && sel_cfg1 )
  234.                         cfg1_reg_out <= common_reg;
  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] };
  243.         end
  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
  254.  
  255.  
  256.         // output data
  257.         assign kbd_out = kbd_reg;
  258.         assign kbd_stb = sel_kbdstb && scs_n_01;
  259.  
  260.         assign mus_out    = common_reg;
  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;
  264.         assign kj_stb     = sel_kj     && scs_n_01;
  265.  
  266.         assign genrst = sel_rstreg && scs_n_01;
  267.  
  268.         assign wait_read = wait_reg;
  269.         assign wait_end = sel_waitreg && scs_n_01;
  270.  
  271.         assign config0 = cfg0_reg_out;
  272.         assign config1 = cfg1_reg_out;
  273.  
  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.  
  286. endmodule
  287.  
  288.