Subversion Repositories pentevo

Rev

Rev 543 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

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