Subversion Repositories ngs

Rev

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

  1. // part of NeoGS project (c) 2007-2008 NedoPC
  2. //
  3.  
  4. // clock:   ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^ (positive edges)
  5. // counter: |00|00|10|11|12|13|14|15|16|17|18|19|1A|1B|1C|1D|1E|1F|00|00|00 // internal!
  6. // sck:   ___________/``\__/``\__/``\__/``\__/``\__/``\__/``\__/``\_______
  7. // sdo:   --------< do7 X do6 X do5 X do4 X do3 X do2 X do1 X do0 >-------
  8. // sdi:   --------< di7 X di6 X di5 X di4 X di3 X di2 X di1 X di0 >-------
  9. // bsync: ________/`````\_________________________________________________
  10. // start: _____/``\_______________________________________________________
  11. // din:   -----<IN>-------------------------------------------------------
  12. // dout:   old old old old old old old old old old old old old | new new new
  13.  
  14. // data on sdo must be latched by slave on rising sck edge. data on sdo changes on falling edge of sck
  15. //
  16. // data from sdi is latched by master on positive edge of sck, while slave changes it on falling edge.
  17. //  WARNING: slave must emit valid di7 bit BEFORE first pulse on sck!
  18. //
  19. // bsync is 1 while do7 is outting, otherwise it is 0
  20. //
  21. // start is synchronous pulse, which starts all transfer and also latches din data on the same clock edge
  22. //  as it is registered high. start can be given anytime (only when halfspeed=0),
  23. //  so it is functioning then as synchronous reset
  24. //
  25. // dout updates with freshly received data at the clock edge in which sck goes high for the last time, thus
  26. //  latching last bit on sdi.
  27. //
  28. // data transfer rate could be as fast as one byte every 16 clock pulses. To achieve that, start must be pulsed
  29. //  high simultaneously with the last high pulse of sck
  30. //
  31. // when halfspeed=1, there must be at least 34 clock pulses between starts
  32.  
  33. module spi(
  34.  
  35.         clock, // system clock
  36.  
  37.         sck,   // SPI bus outputs
  38.         sdo,   //
  39.         sdi,   //
  40.         bsync, // and bsync for vs1001
  41.  
  42.         start, // positive strobe that starts transfer
  43.  
  44.         halfspeed, // =0 - sck full speed (1/2 of clock), =1 - half (1/4 of clock)
  45.  
  46.         din,  // input
  47.         dout  // and output 8bit busses
  48. );
  49.  
  50.         input clock;
  51.  
  52.  
  53.         output sck;
  54.         wire   sck;
  55.  
  56.         output sdo;
  57.  
  58.         input sdi;
  59.  
  60.         output reg bsync;
  61.  
  62.         input start;
  63.  
  64.         input halfspeed;
  65.  
  66.         input [7:0] din;
  67.  
  68.         output reg [7:0] dout;
  69.  
  70.  
  71.  
  72.         // internal regs
  73.  
  74.         reg [4:0] counter; // governs transmission
  75.  
  76.         wire enable_n; // =1 when transmission in progress
  77.  
  78.         reg [6:0] shiftin; // shifting in data from sdi before emitting it on dout
  79.  
  80.         reg [7:0] shiftout; // shifting out data to the sdo
  81.  
  82.         wire ena_shout_load; // enable load of shiftout register
  83.  
  84.         reg g_ena;
  85.  
  86.  
  87.         initial // for simulation only!
  88.         begin
  89.                 counter = 5'b10000;
  90.                 shiftout = 8'd0;
  91.                 shiftout = 7'd0;
  92.                 bsync = 1'd0;
  93.                 dout <= 1'b0;
  94.         end
  95.  
  96.  
  97.  
  98.  
  99.         // sck is low bit of counter
  100.         assign sck = counter[0];
  101.  
  102.         // enable_n is high bit of counter
  103.         assign enable_n = counter[4];
  104.  
  105.         // sdo is high bit of shiftout
  106.         assign sdo = shiftout[7];
  107.  
  108.         assign ena_shout_load = (start | sck) & g_ena;
  109.  
  110.  
  111.  
  112.  
  113.         always @(posedge clock)
  114.         begin
  115.                 if( g_ena )
  116.                 begin
  117.                         if( start )
  118.                         begin
  119.                                 counter <= 5'b00000; // enable_n = 0; sck = 0;
  120.                                 bsync <= 1'b1; // begin bsync pulse
  121.                         end
  122.                         else
  123.                         begin
  124.                                 if( !sck ) // on the rising edge of sck
  125.                                 begin
  126.                           shiftin[6:0] <= { shiftin[5:0], sdi };
  127.  
  128.                                         if( (&counter[3:1]) && (!enable_n) )
  129.                                                 dout <= { shiftin[6:0], sdi }; // update dout at the last sck rising edge
  130.                                 end
  131.                                 else // on the falling edge of sck
  132.                                 begin
  133.                                         bsync <= 1'b0;
  134.                                 end
  135.  
  136.                                 if( !enable_n )
  137.                                         counter <= counter + 5'd1;
  138.                         end
  139.                 end
  140.         end
  141.  
  142.  
  143.         // shiftout treatment is done so just to save LCELLs in acex1k
  144.         always @(posedge clock)
  145.         begin
  146.                 if( ena_shout_load )
  147.                 begin
  148.                         if( start )
  149.                                 shiftout <= din;
  150.                         else // sck
  151.                                 shiftout[7:0] <= { shiftout[6:0], shiftout[0] }; // last bit remains after end of exchange
  152.                 end
  153.         end
  154.  
  155.  
  156.         // half speed - governed by g_ena
  157.         always @(posedge clock)
  158.         begin
  159.                 if( halfspeed )
  160.                 begin
  161.                         if( start )
  162.                                 g_ena <= 1'b0;
  163.                         else if( enable_n )
  164.                                 g_ena <= 1'b1;
  165.                         else
  166.                                 g_ena <= ~g_ena;
  167.                 end
  168.                 else
  169.                         g_ena <= 1'b1;
  170.         end
  171.  
  172.  
  173.  
  174. endmodule
  175.