Subversion Repositories pentevo

Rev

Rev 543 | 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. // SPI mode 0 8-bit master module
  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.  
  25. // short diagram for speed=0 (Fclk/Fspi=2, no rdy shown)
  26. //
  27. // clock:   ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^ (positive edges)
  28. // counter: |00|00|10|11|12|13|14|15|16|17|18|19|1A|1B|1C|1D|1E|1F|00|00|00 // internal!
  29. // sck:   ___________/``\__/``\__/``\__/``\__/``\__/``\__/``\__/``\_______
  30. // sdo:   --------< do7 X do6 X do5 X do4 X do3 X do2 X do1 X do0 >-------
  31. // sdi:   --------< di7 X di6 X di5 X di4 X di3 X di2 X di1 X di0 >-------
  32. // bsync: ________/`````\_________________________________________________
  33. // start: _____/``\_______________________________________________________
  34. // din:   -----<IN>-------------------------------------------------------
  35. // dout:   old old old old old old old old old old old old old | new new new
  36. //
  37. // data on sdo must be latched by slave on rising sck edge. data on sdo changes on falling edge of sck
  38. //
  39. // data from sdi is latched by master on positive edge of sck, while slave changes it on falling edge.
  40. //  WARNING: slave must emit valid di7 bit BEFORE first pulse on sck!
  41. //
  42. // bsync is 1 while do7 is outting, otherwise it is 0
  43. //
  44. // start is synchronous pulse, which starts all transfer and also latches din data on the same clock edge
  45. //  as it is registered high. start can be given anytime (only when speed=0),
  46. //  so it is functioning then as synchronous reset. when speed!=0, there is global enable for majority of
  47. //  flipflops in the module, so start can't be accepted at any time
  48. //
  49. // dout updates with freshly received data at the clock edge in which sck goes high for the last time, thus
  50. //  latching last bit on sdi.
  51. //
  52. // sdo emits last bit shifted out after the transfer end
  53. //
  54. // when speed=0, data transfer rate could be as fast as one byte every 16 clock pulses. To achieve that,
  55. //   start must be pulsed high simultaneously with the last high pulse of sck
  56. //
  57. // speed[1:0] determines Fclk/Fspi
  58. //
  59. //  speed | Fclk/Fspi
  60. //  ------+----------
  61. //  2'b00 | 2
  62. //  2'b01 | 4
  63. //  2'b10 | 8
  64. //  2'b11 | 16
  65. //
  66. // for speed=0 you can start new transfer as fast as every 16 clocks
  67. // for speed=1 - every 34 clocks.
  68. // alternatively, you can check rdy output: it goes to 0 after start pulse and when it goes back to 1, you can
  69. // issue another start at the next clock cycle. See spi2_modelled.png and .zip (modelsim project)
  70. //
  71. // warning: if using rdy-driven transfers and speed=0, new transfer will be started every 18 clocks.
  72. //  it is recommended to use rdy-driven transfers when speed!=0
  73. //
  74. // warning: this module does not contain asynchronous reset. Provided clock is stable, start=0
  75. //  and speed=0, module returns to initial ready state after maximum of 18+8=26 clocks. To reset module
  76. //  to the known state from any operational state, set speed=0 and start=1 for 8 clocks
  77. //  (that starts Fclk/Fspi=2 speed transfer for sure), then remain start=0, speed=0 for at least 18 clocks.
  78.  
  79. module spi2(
  80.  
  81.         clock, // system clock
  82.  
  83.         sck,   // SPI bus pins...
  84.         sdo,   //
  85.         sdi,   //
  86.         bsync, // ...and bsync for vs1001
  87.  
  88.         start, // positive strobe that starts transfer
  89.         rdy,   // ready (idle) - when module can accept data
  90.  
  91.         speed, // =2'b00 - sck full speed (1/2 of clock), =2'b01 - half (1/4 of clock), =2'b10 - one fourth (1/8 of clock), =2'b11 - one eighth (1/16 of clock)
  92.  
  93.         din,  // input
  94.         dout  // and output 8bit busses
  95. );
  96.  
  97.         input clock;
  98.  
  99.  
  100.         output sck;
  101.         wire   sck;
  102.  
  103.         output sdo;
  104.  
  105.         input sdi;
  106.  
  107.         output reg bsync;
  108.  
  109.         input start;
  110.  
  111.         output rdy;
  112.  
  113.  
  114.         input [1:0] speed;
  115.  
  116.         input [7:0] din;
  117.  
  118.         output reg [7:0] dout;
  119.  
  120.  
  121.  
  122.         // internal regs
  123.  
  124.         reg [4:0] counter; // governs transmission
  125.  
  126.         wire enable_n; // =1 when transmission in progress
  127.  
  128.         reg [6:0] shiftin; // shifting in data from sdi before emitting it on dout
  129.  
  130.         reg [7:0] shiftout; // shifting out data to the sdo
  131.  
  132.         wire ena_shout_load; // enable load of shiftout register
  133.  
  134.         wire g_ena;
  135.         reg [2:0] wcnt;
  136.  
  137.  
  138.         initial // for simulation only!
  139.         begin
  140.                 counter = 5'b10000;
  141.                 shiftout = 8'd0;
  142.                 shiftout = 7'd0;
  143.                 bsync = 1'd0;
  144.                 dout = 1'b0;
  145.         end
  146.  
  147.  
  148.         // rdy is enable_n
  149.         assign rdy = enable_n;
  150.  
  151.         // sck is low bit of counter
  152.         assign sck = counter[0];
  153.  
  154.         // enable_n is high bit of counter
  155.         assign enable_n = counter[4];
  156.  
  157.         // sdo is high bit of shiftout
  158.         assign sdo = shiftout[7];
  159.  
  160.         assign ena_shout_load = (start | sck) & g_ena;
  161.  
  162.  
  163.  
  164.  
  165.         always @(posedge clock)
  166.         begin
  167.                 if( g_ena )
  168.                 begin
  169.                         if( start )
  170.                         begin
  171.                                 counter <= 5'b00000; // enable_n = 0; sck = 0;
  172.                                 bsync <= 1'b1; // begin bsync pulse
  173.                         end
  174.                         else
  175.                         begin
  176.                                 if( !sck ) // on the rising edge of sck
  177.                                 begin
  178.                           shiftin[6:0] <= { shiftin[5:0], sdi };
  179.  
  180.                                         if( (&counter[3:1]) && (!enable_n) )
  181.                                                 dout <= { shiftin[6:0], sdi }; // update dout at the last sck rising edge
  182.                                 end
  183.                                 else // on the falling edge of sck
  184.                                 begin
  185.                                         bsync <= 1'b0;
  186.                                 end
  187.  
  188.                                 if( !enable_n )
  189.                                         counter <= counter + 5'd1;
  190.                         end
  191.                 end
  192.         end
  193.  
  194.  
  195.         // shiftout treatment is done so just to save LCELLs in acex1k
  196.         always @(posedge clock)
  197.         begin
  198.                 if( ena_shout_load )
  199.                 begin
  200.                         if( start )
  201.                                 shiftout <= din;
  202.                         else // sck
  203.                                 shiftout[7:0] <= { shiftout[6:0], shiftout[0] }; // last bit remains after end of exchange
  204.                 end
  205.         end
  206.  
  207.  
  208.         // slow speeds - governed by g_ena
  209.         always @(posedge clock)
  210.         begin
  211.                 if( speed!=2'b00 )
  212.                 begin
  213.                         if( start )
  214.                                 wcnt <= 3'b001;
  215.                         else if( enable_n )
  216.                                 wcnt <= 3'b000;
  217.                         else
  218.                                 wcnt <= wcnt + 3'd1;
  219.                 end
  220.                 else
  221.                         wcnt <= 3'b000;
  222.         end
  223.  
  224.         assign g_ena = (speed==2'b00) ? 1'b1 :
  225.                        (speed==2'b01) ? (wcnt[0]  == 1'b0   ) :
  226.                        (speed==2'b10) ? (wcnt[1:0]== 2'b00  ) :
  227.                                         (wcnt[2:0]== 3'b000 ) ;
  228.  
  229.  
  230. endmodule
  231.  
  232.